#
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
# openUBMC is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#         http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.
#

"""
嵌套函数异步代码生成器

生成异步协程代码
"""

from dataclasses import dataclass
from typing import Optional, Any

from mcpy.codegen.core.context import CodeGenContext
from mcpy.codegen.core.generator import get_global_generator
from mcpy.ir.statements.assignment import IRAssign
from mcpy.ir.statements.control import IRIf, IRForRange, IRWhile, IRReturn
from mcpy.ir.statements.exception import IRTryExcept, IRExceptionHandler
from mcpy.ir.expressions.await_expr import IRAwait
from mcpy.ir.expressions.basic import IRName
from mcpy.ir.declarations.function import IRFunctionNode
from .type_inference import get_await_result_type, get_local_var_type
from .utils import fix_global_async_struct_call


@dataclass
class AsyncGenContext:
    """异步代码生成上下文"""

    # 基础上下文
    context: CodeGenContext  # 代码生成上下文
    statements: list  # IR 语句列表
    state_vars: dict  # 成员变量字典 {var_name: type_info}
    header_vars: set  # 函数头变量集合
    async_dataflow: Any  # 异步数据流信息
    statement_block_node: Any  # 当前语句块的 IR 节点
    indent: str  # 当前缩进

    # await 结果变量跟踪（可选）
    prev_await_result_var: Optional[str] = None  # 前一个 await 的结果变量名
    prev_await_result_type: Optional[str] = None  # 前一个 await 的结果类型
    prev_await_unit: Optional[Any] = (
        None  # 前一个 await 所在的 Unit（用于获取 try_block_id）
    )

    # try包裹控制（可选）
    defer_try_wrapping: bool = False  # 是否延迟try包裹（在try块内部生成代码时为True）

    def with_indent(self, new_indent: str) -> "AsyncGenContext":
        """创建新上下文，使用新的缩进"""
        return AsyncGenContext(
            context=self.context,
            statements=self.statements,
            state_vars=self.state_vars,
            header_vars=self.header_vars,
            async_dataflow=self.async_dataflow,
            statement_block_node=self.statement_block_node,
            indent=new_indent,
            prev_await_result_var=self.prev_await_result_var,
            prev_await_result_type=self.prev_await_result_type,
            prev_await_unit=self.prev_await_unit,
            defer_try_wrapping=self.defer_try_wrapping,
        )

    def with_statement_block(self, new_block: Any) -> "AsyncGenContext":
        """创建新上下文，使用新的语句块"""
        return AsyncGenContext(
            context=self.context,
            statements=new_block.statements if hasattr(new_block, "statements") else [],
            state_vars=self.state_vars,
            header_vars=self.header_vars,
            async_dataflow=self.async_dataflow,
            statement_block_node=new_block,
            indent=self.indent,
            prev_await_result_var=self.prev_await_result_var,
            prev_await_result_type=self.prev_await_result_type,
            prev_await_unit=self.prev_await_unit,
            defer_try_wrapping=self.defer_try_wrapping,
        )

    def with_await_result(
        self,
        var_name: Optional[str],
        var_type: Optional[str],
        unit: Optional[Any] = None,
    ) -> "AsyncGenContext":
        """创建新上下文，更新 await 结果变量信息"""
        return AsyncGenContext(
            context=self.context,
            statements=self.statements,
            state_vars=self.state_vars,
            header_vars=self.header_vars,
            async_dataflow=self.async_dataflow,
            statement_block_node=self.statement_block_node,
            indent=self.indent,
            prev_await_result_var=var_name,
            prev_await_result_type=var_type,
            prev_await_unit=unit,
            defer_try_wrapping=self.defer_try_wrapping,
        )


class AsyncCodeGenerator:
    """异步代码生成器"""

    def __init__(self):
        pass

    def _find_current_segments_and_units(self, async_dataflow, statement_block_node):
        """找到当前语句块对应的 Segments 和 Units

        Args:
            async_dataflow: 异步数据流信息
            statement_block_node: 当前语句块的 IR 节点

        Returns:
            (current_segments, current_units): Segments 和 Units 列表
        """
        current_segments = [
            seg
            for seg in async_dataflow.segments
            if id(seg.statement_block_node) == id(statement_block_node)
        ]

        current_units = [
            unit
            for unit in async_dataflow.units
            if id(unit.statement_block_node) == id(statement_block_node)
        ]

        return current_segments, current_units

    def _handle_no_segments_case(self, gen_ctx: AsyncGenContext) -> list[str]:
        """处理没有 Segments 的情况（纯同步代码或回退逻辑）

        Args:
            gen_ctx: 异步代码生成上下文

        Returns:
            生成的代码行列表
        """
        generator = get_global_generator()
        code_lines = []

        # 检查是否有 await 语句
        has_await = any(
            isinstance(s, IRAssign) and isinstance(s.value, IRAwait)
            for s in gen_ctx.statements
        )

        if not has_await:
            # 纯同步代码，直接生成
            # 但需要特殊处理 return 语句，因为异步函数中的 return 应该使用 set_result
            from mcpy.ir.statements.control import IRReturn

            for stmt in gen_ctx.statements:
                if isinstance(stmt, IRReturn):
                    # return 语句需要特殊处理
                    lines, _, _ = self._generate_return_statement(
                        stmt, gen_ctx, should_merge_with_next=None
                    )
                    code_lines.extend(lines)
                else:
                    stmt_code = generator.generate_statement(stmt, gen_ctx.context)
                    if stmt_code:
                        code_lines.append(f"{gen_ctx.indent}{stmt_code}")
            return code_lines
        else:
            # 有 await 但没有 Segment，这不应该发生
            # 回退到旧的生成方式
            # 注意：这里需要导入 ControlFlowGenerator，但为了避免循环依赖，
            # 暂时保留这个回退逻辑，后续可以优化
            from .control_flow_generator import ControlFlowGenerator

            control_flow_gen = ControlFlowGenerator()
            fallback_code = control_flow_gen.generate_statements_with_await(
                gen_ctx.statements,
                gen_ctx.state_vars,
                gen_ctx.context,
                gen_ctx.indent,
            )
            return fallback_code.split("\n") if fallback_code else []

    def _identify_units_need_defer(
        self, current_units, gen_ctx: AsyncGenContext
    ) -> set:
        """判断哪些 Unit 需要延迟生成（情况3：有 await 且有局部变量定义）

        Args:
            current_units: 当前语句块的 Units 列表
            gen_ctx: 异步代码生成上下文

        Returns:
            需要延迟生成的 unit_id 集合
        """
        units_need_defer = set()

        for unit in current_units:
            # 条件1：unit 必须有 await
            if not unit.has_await:
                continue

            # 条件2：unit 中定义的变量中有局部变量（不在 state_vars 或 header_vars 中）
            has_local_var_def = False
            for var_name in unit.variables_defined:
                if (
                    var_name not in gen_ctx.state_vars
                    and var_name not in gen_ctx.header_vars
                ):
                    has_local_var_def = True
                    break

            if has_local_var_def:
                units_need_defer.add(unit.unit_id)

        return units_need_defer

    def _get_exception_cpp_type(
        self, exc_type, context: CodeGenContext
    ) -> Optional[str]:
        """获取异常的 C++ 类型名称

        Returns:
            异常类型名称，或 None 表示 catch(...) 捕获所有异常
        """
        if exc_type is None:
            # except: 捕获所有异常 - 返回 None 表示使用 catch(...)
            return None

        # 提取异常类型名称
        from mcpy.ir.expressions.basic import IRName
        from mcpy.ir.expressions.access import IRAttribute

        exc_type_name = None
        if isinstance(exc_type, IRName):
            exc_type_name = exc_type.id
        elif isinstance(exc_type, IRAttribute):
            if isinstance(exc_type.value, IRName):
                exc_type_name = exc_type.attr

        # 查找异常类型的 C++ 映射
        if exc_type_name and context.current_node:
            symbol = context.current_node.lookup_symbol(exc_type_name)
            if symbol and hasattr(symbol, "type_config") and symbol.type_config:
                cpp_type = symbol.type_config.get("cpp_type")
                if cpp_type:
                    # 添加必要的头文件
                    includes = symbol.type_config.get("includes", [])
                    for include in includes:
                        context.require_include(include)
                    return cpp_type

        # 默认使用通用异常类型
        return "mc::exception"

    def _wrap_with_try_catch(
        self,
        code_lines: list[str],
        try_block_id: Optional[int],
        indent: str,
        clear_state: bool = False,
    ) -> list[str]:
        """将代码行包装在 try/catch 块中

        Args:
            code_lines: 要包装的代码行列表
            try_block_id: try 块 ID，如果为 None 则不包装
            indent: 缩进字符串
            clear_state: 是否清除协程状态（True=CO_CLEAR_STATE, False=CO_KEEP_STATE）

        Returns:
            包装后的代码行列表
        """
        if try_block_id is None or not code_lines:
            return code_lines

        wrapped_lines = []
        wrapped_lines.append(f"{indent}try {{")
        for line in code_lines:
            wrapped_lines.append(line)

        if clear_state:
            wrapped_lines.append(
                f"{indent}}} co_catch({try_block_id}, CO_CLEAR_STATE);"
            )
        else:
            wrapped_lines.append(f"{indent}}} co_catch({try_block_id});")

        return wrapped_lines

    def _wrap_try_body_lines(
        self, try_body_lines: list[str], try_id: int, indent: str
    ) -> list[str]:
        """统一处理try块体的包裹，合并连续的普通语句

        这个方法接收try块内部生成的代码（延迟了try包裹），
        然后智能地添加try包裹，合并连续的普通语句。

        策略：
        1. 识别co_yield块（不包裹）
        2. 合并连续的普通语句，统一包裹在一个try块中
        3. 遇到co_yield块时，输出之前累积的普通语句

        Args:
            try_body_lines: try块内部生成的代码行（延迟了try包裹）
            try_id: try块ID
            indent: 缩进字符串

        Returns:
            包裹后的代码行列表
        """
        if not try_body_lines:
            return []

        result = []
        accumulated_lines = []  # 累积的普通语句
        i = 0

        while i < len(try_body_lines):
            line = try_body_lines[i].strip()

            # 检测co_yield块的开始
            if line.startswith("co_yield"):
                # 先输出累积的普通语句
                if accumulated_lines:
                    result.append(f"{indent}try {{")
                    result.extend(accumulated_lines)
                    result.append(f"{indent}}} co_catch({try_id});")
                    result.append("")  # 空行
                    accumulated_lines = []

                # 输出co_yield块（保持原样，不包裹）
                result.append(try_body_lines[i])
                i += 1

                # 继续处理co_yield块内的代码和结束
                # 查找co_yield块的结束（匹配的}或} co_catch）
                brace_count = 0
                started = False
                while i < len(try_body_lines):
                    current_line = try_body_lines[i]
                    result.append(current_line)

                    stripped = current_line.strip()
                    # 计算花括号
                    for ch in stripped:
                        if ch == "{":
                            brace_count += 1
                            started = True
                        elif ch == "}":
                            brace_count -= 1

                    i += 1

                    # 检测co_yield块结束
                    if started and brace_count == 0:
                        # 检查下一行是否是co_catch
                        if i < len(try_body_lines) and "co_catch" in try_body_lines[i]:
                            result.append(try_body_lines[i])
                            i += 1
                        break

                # 添加空行分隔
                if i < len(try_body_lines):
                    result.append("")
            else:
                # 普通语句，累积
                accumulated_lines.append(try_body_lines[i])
                i += 1

        # 输出最后累积的普通语句
        if accumulated_lines:
            result.append(f"{indent}try {{")
            result.extend(accumulated_lines)
            result.append(f"{indent}}} co_catch({try_id});")

        return result

    def _generate_await_result_var_assignment(
        self,
        var_name: str,
        var_type: str,
        gen_ctx: AsyncGenContext,
        try_block_id: Optional[int] = None,
        next_in_same_try_block: bool = False,
    ) -> list[str]:
        """生成 await 结果变量的赋值代码

        根据新设计：
        - 如果 await 之后的代码仍然在同一个 try 块内，直接使用 get()，异常会被后续的 try 块捕获
        - 如果 await 之后的代码不在 try 块内，使用 has_exception() 检查并获取异常

        Args:
            var_name: 变量名
            var_type: 变量类型
            gen_ctx: 异步代码生成上下文
            try_block_id: try 块 ID，如果为 None 则不添加异常处理
            next_in_same_try_block: 后续代码是否还在同一个 try 块内

        Returns:
            生成的代码行列表
        """
        state_vars = gen_ctx.state_vars
        header_vars = gen_ctx.header_vars
        indent = gen_ctx.indent

        if var_name in state_vars or var_name in header_vars:
            # 成员变量或函数头变量：只赋值
            code_line = f"{indent}{var_name} = __resume_value.get<{var_type}>();"
        else:
            # 局部变量：需要声明
            code_line = (
                f"{indent}{var_type} {var_name} = __resume_value.get<{var_type}>();"
            )

        # 根据 try_block_id 决定异常处理方式
        if try_block_id is not None:
            # 在 try 块内
            if next_in_same_try_block:
                # 后续代码还在同一个 try 块内：直接使用 get()，异常会被后续的 try 块捕获
                code_lines = []
                # 直接使用 get()，不需要 try 块包裹，异常会被后续的 try 块捕获
                if var_name not in state_vars and var_name not in header_vars:
                    # 局部变量：先声明，再赋值
                    code_lines.append(f"{indent}{var_type} {var_name};")
                    code_lines.append(
                        f"{indent}{var_name} = __resume_value.get<{var_type}>();"
                    )
                else:
                    # 成员变量或函数头变量：直接赋值
                    code_lines.append(code_line)
                return code_lines
            else:
                # 后续代码不在 try 块内：使用 has_exception() 检查，避免额外的 try 块
                code_lines = []
                # 对于局部变量，需要先声明变量（在 goto 之前），避免 C++ 跳转规则问题
                if var_name not in state_vars and var_name not in header_vars:
                    # 局部变量：先声明，再赋值
                    code_lines.append(f"{indent}{var_type} {var_name};")
                    code_lines.append(f"{indent}co_check_exception({try_block_id});")
                    code_lines.append(
                        f"{indent}{var_name} = __resume_value.get<{var_type}>();"
                    )
                else:
                    # 成员变量或函数头变量：先检查异常，再赋值
                    code_lines.append(f"{indent}co_check_exception({try_block_id});")
                    code_lines.append(code_line)

                return code_lines
        else:
            # 不在 try 块内：直接赋值
            return [code_line]

    def _find_stmt_unit(self, global_stmt_idx, current_units):
        """查找语句所属的最小代码单元

        Args:
            global_stmt_idx: 语句在全局的索引
            current_units: 当前语句块的 Units 列表

        Returns:
            语句所属的 Unit，如果未找到则返回 None
        """
        for unit in current_units:
            if unit.start_stmt_index <= global_stmt_idx < unit.end_stmt_index:
                return unit
        return None

    def _should_defer_statement_to_co_yield(
        self,
        stmt,
        stmt_unit,
        global_stmt_idx: int,
        gen_ctx: AsyncGenContext,
        units_need_defer: set,
    ) -> bool:
        """判断当前语句是否应该延迟到 co_yield 块中生成

        Args:
            stmt: 当前语句
            stmt_unit: 语句所属的 Unit
            global_stmt_idx: 语句在全局的索引
            gen_ctx: 异步代码生成上下文
            units_need_defer: 需要延迟生成的 unit_id 集合

        Returns:
            True 表示应该延迟生成
        """
        should_defer = False
        if stmt_unit and stmt_unit.unit_id in units_need_defer:
            # 检查当前语句是否在 await 之前
            # 找到 Unit 中的 await 语句位置
            unit_stmts = gen_ctx.statements[
                stmt_unit.start_stmt_index : stmt_unit.end_stmt_index
            ]
            await_idx = None
            for idx, unit_stmt in enumerate(unit_stmts):
                if isinstance(unit_stmt, IRAssign) and isinstance(
                    unit_stmt.value, IRAwait
                ):
                    await_idx = idx
                    break

            if await_idx is not None:
                # 计算当前语句在 Unit 中的索引
                current_idx_in_unit = global_stmt_idx - stmt_unit.start_stmt_index
                if current_idx_in_unit < await_idx:
                    # 当前语句在 await 之前，需要延迟
                    should_defer = True

        return should_defer

    def _generate_if_statement(
        self, stmt: IRIf, gen_ctx: AsyncGenContext, should_defer: bool = False
    ) -> list[str]:
        """生成 if 语句代码

        Args:
            stmt: if 语句节点
            gen_ctx: 异步代码生成上下文
            should_defer: 是否应该延迟生成

        Returns:
            生成的代码行列表
        """
        if should_defer:
            return []

        generator = get_global_generator()
        code_lines = []

        # 递归处理子语句块
        cond_code = generator.generate_expression(stmt.test, gen_ctx.context)
        code_lines.append(f"{gen_ctx.indent}if ({cond_code}) {{")

        if stmt.then_body:
            then_ctx = gen_ctx.with_statement_block(stmt.then_body).with_indent(
                gen_ctx.indent + "    "
            )
            then_lines = self.generate_async_statements(then_ctx)
            code_lines.extend(then_lines)

        if stmt.else_body:
            code_lines.append(f"{gen_ctx.indent}}} else {{")
            else_ctx = gen_ctx.with_statement_block(stmt.else_body).with_indent(
                gen_ctx.indent + "    "
            )
            else_lines = self.generate_async_statements(else_ctx)
            code_lines.extend(else_lines)

        code_lines.append(f"{gen_ctx.indent}}}")
        return code_lines

    def _generate_for_range_statement(
        self, stmt: IRForRange, gen_ctx: AsyncGenContext, should_defer: bool = False
    ) -> list[str]:
        """生成 for 循环代码

        Args:
            stmt: for 循环节点
            gen_ctx: 异步代码生成上下文
            should_defer: 是否应该延迟生成

        Returns:
            生成的代码行列表
        """
        if should_defer:
            return []

        generator = get_global_generator()
        code_lines = []

        loop_var = stmt.var.id if isinstance(stmt.var, IRName) else str(stmt.var)
        start_code = generator.generate_expression(stmt.start, gen_ctx.context)
        end_code = generator.generate_expression(stmt.end, gen_ctx.context)
        step_code = (
            generator.generate_expression(stmt.step, gen_ctx.context)
            if stmt.step
            else "1"
        )

        need_decl = (
            loop_var not in gen_ctx.state_vars and loop_var not in gen_ctx.header_vars
        )

        if need_decl:
            code_lines.append(
                f"{gen_ctx.indent}for (int {loop_var} = {start_code}; {loop_var} < {end_code}; {loop_var} += {step_code}) {{"
            )
        else:
            code_lines.append(f"{gen_ctx.indent}{loop_var} = {start_code};")
            code_lines.append(
                f"{gen_ctx.indent}for (; {loop_var} < {end_code}; {loop_var} += {step_code}) {{"
            )

        if stmt.body:
            body_ctx = gen_ctx.with_statement_block(stmt.body).with_indent(
                gen_ctx.indent + "    "
            )
            body_lines = self.generate_async_statements(body_ctx)
            code_lines.extend(body_lines)

        code_lines.append(f"{gen_ctx.indent}}}")
        return code_lines

    def _generate_while_statement(
        self, stmt: IRWhile, gen_ctx: AsyncGenContext, should_defer: bool = False
    ) -> list[str]:
        """生成 while 循环代码

        Args:
            stmt: while 循环节点
            gen_ctx: 异步代码生成上下文
            should_defer: 是否应该延迟生成

        Returns:
            生成的代码行列表
        """
        if should_defer:
            return []

        generator = get_global_generator()
        code_lines = []

        cond_code = generator.generate_expression(stmt.test, gen_ctx.context)
        code_lines.append(f"{gen_ctx.indent}while ({cond_code}) {{")

        if stmt.body:
            body_ctx = gen_ctx.with_statement_block(stmt.body).with_indent(
                gen_ctx.indent + "    "
            )
            body_lines = self.generate_async_statements(body_ctx)
            code_lines.extend(body_lines)

        code_lines.append(f"{gen_ctx.indent}}}")
        return code_lines

    def _generate_await_expression_code(self, stmt, context, statement_block_node):
        """生成 await 表达式的 C++ 代码并修正全局异步函数调用

        Args:
            stmt: await 赋值语句节点
            context: 代码生成上下文
            statement_block_node: 当前语句块的 IR 节点

        Returns:
            生成的 await 表达式代码
        """
        generator = get_global_generator()
        await_expr_code = generator.generate_expression(stmt.value.value, context)

        # 修正全局异步函数 struct 的调用语法
        current_func = context.get_extension_param("current_node")
        if current_func:
            await_expr_code = fix_global_async_struct_call(
                stmt.value.value, await_expr_code, current_func
            )
        else:
            # 如果 context 中没有 current_node，尝试从 statement_block_node 向上查找
            node = statement_block_node
            while node and not isinstance(node, IRFunctionNode):
                if hasattr(node, "parent"):
                    node = node.parent
                else:
                    node = None
            if node:
                await_expr_code = fix_global_async_struct_call(
                    stmt.value.value, await_expr_code, node
                )

        return await_expr_code

    def _check_has_local_vars_before_await(
        self, stmt_unit, global_stmt_idx: int, gen_ctx: AsyncGenContext
    ) -> bool:
        """检查当前最小代码单元中是否有其他局部变量定义（在 await 之前）

        Args:
            stmt_unit: 语句所属的 Unit
            global_stmt_idx: await 语句在全局的索引
            gen_ctx: 异步代码生成上下文

        Returns:
            True 表示有局部变量定义
        """
        if not stmt_unit:
            return False

        # 获取当前单元中 await 之前的语句
        unit_stmts = gen_ctx.statements[stmt_unit.start_stmt_index : global_stmt_idx]

        # 检查这些语句中是否有局部变量定义
        for unit_stmt in unit_stmts:
            if not isinstance(unit_stmt, IRAssign):
                continue

            target = unit_stmt.get_target_expr()
            if not target or not isinstance(target, IRName):
                continue

            var_name = target.id
            # 检查是否是局部变量（不是成员变量，也不是函数头变量）
            if var_name in gen_ctx.state_vars or var_name in gen_ctx.header_vars:
                continue

            # 检查是否是变量声明（而不是重新赋值）
            is_decl = unit_stmt.get_extension_param("is_variable_declaration", True)
            if is_decl:
                return True

        return False

    def _should_use_co_yield_block(
        self,
        gen_ctx: AsyncGenContext,
        stmt_unit,
        global_stmt_idx: int,
        units_need_defer: set,
    ) -> bool:
        """判断是否应该使用 co_yield 块（情况3 vs 情况2）

        Args:
            gen_ctx: 异步代码生成上下文
            stmt_unit: 语句所属的 Unit
            global_stmt_idx: await 语句在全局的索引
            units_need_defer: 需要延迟生成的 unit_id 集合

        Returns:
            True 表示使用 co_yield 块（情况3）
        """
        # 条件1：当前 unit 需要延迟生成
        # 这包括：await 之前的局部变量定义、await 结果变量是局部变量
        if stmt_unit and stmt_unit.unit_id in units_need_defer:
            return True

        # 条件2：前一个 await 的结果变量是局部变量
        # 需要在 co_yield 块中声明，所以需要 co_yield 块
        prev_await_result_var = gen_ctx.prev_await_result_var
        if prev_await_result_var:
            if (
                prev_await_result_var not in gen_ctx.state_vars
                and prev_await_result_var not in gen_ctx.header_vars
            ):
                return True

        return False

    def _generate_co_yield_return(
        self,
        gen_ctx: AsyncGenContext,
        await_expr_code: str,
        stmt_unit=None,
    ) -> tuple[list[str], Optional[str], Optional[str]]:
        """生成 co_yield_return await(...) 代码（情况2）

        根据新设计：
        - 如果 await 在 try 块中，生成 `co_yield try { return await(...); } catch() {}` 形式
        - 如果 await 不在 try 块中，生成 `co_yield_return await(...)` 形式

        Args:
            gen_ctx: 异步代码生成上下文
            await_expr_code: await 表达式代码
            stmt_unit: 语句所属的 Unit（用于获取 try_block_id）

        Returns:
            (code_lines, new_prev_var, new_prev_type): 代码行列表和更新后的前一个 await 变量信息
        """
        code_lines = []
        prev_await_result_var = gen_ctx.prev_await_result_var
        prev_await_result_type = gen_ctx.prev_await_result_type

        # 先处理前一个 await 的结果变量赋值（如果是成员/函数头变量）
        if (
            prev_await_result_var
            and prev_await_result_type
            and (
                prev_await_result_var in gen_ctx.state_vars
                or prev_await_result_var in gen_ctx.header_vars
            )
        ):
            # 检查是否需要异常处理
            prev_unit = None
            if gen_ctx.async_dataflow:
                for unit in gen_ctx.async_dataflow.units:
                    if (
                        unit.variables_defined
                        and prev_await_result_var in unit.variables_defined
                    ):
                        prev_unit = unit
                        break

            result_lines = self._generate_await_result_var_assignment(
                prev_await_result_var,
                prev_await_result_type,
                gen_ctx,
                try_block_id=prev_unit.try_block_id if prev_unit else None,
                next_in_same_try_block=False,
            )
            code_lines.extend(result_lines)
            prev_await_result_var = None
            prev_await_result_type = None

        # 生成 await 调用，根据 try_block_id 决定是否使用 co_yield try 形式
        if stmt_unit and stmt_unit.try_block_id is not None:
            # 在 try 块内，使用 co_yield try { return await(...); } co_catch(try_id) 形式
            try_block_id = stmt_unit.try_block_id

            # 检查是否有 parent_try_block_id（即是否是嵌套的内层 try 块）
            parent_try_id = stmt_unit.parent_try_block_id

            if parent_try_id is not None:
                # 嵌套 try 块：使用简化的单层 co_yield try
                # co_catch 会路由到正确的 co_except，在那里构造异常处理链
                code_lines.append(f"{gen_ctx.indent}co_yield try {{")
                code_lines.append(
                    f"{gen_ctx.indent}    return await({await_expr_code}, __ctx);"
                )
                code_lines.append(
                    f"{gen_ctx.indent}}} co_catch({try_block_id}, CO_CLEAR_STATE);"
                )
                code_lines.append("")  # 空行，提高可读性
            else:
                # 非嵌套 try 块：直接使用 co_yield try
                code_lines.append(f"{gen_ctx.indent}co_yield try {{")
                code_lines.append(
                    f"{gen_ctx.indent}    return await({await_expr_code}, __ctx);"
                )
                code_lines.append(
                    f"{gen_ctx.indent}}} co_catch({try_block_id}, CO_CLEAR_STATE);"
                )
                code_lines.append("")  # 空行，提高可读性
        else:
            # 不在 try 块内，使用原来的合并形式
            code_lines.append(
                f"{gen_ctx.indent}co_yield_return await({await_expr_code}, __ctx);"
            )

        return code_lines, prev_await_result_var, prev_await_result_type

    def _generate_return_statement(
        self,
        stmt: IRReturn,
        gen_ctx: AsyncGenContext,
        should_merge_with_next: Optional[int] = None,
    ) -> tuple[list[str], Optional[str], Optional[str]]:
        """生成 return 语句代码

        Args:
            stmt: return 语句节点
            gen_ctx: 异步代码生成上下文
            should_merge_with_next: 如果为 try_block_id，表示应该与 await 结果获取合并到同一个 try 块

        Returns:
            (code_lines, new_prev_var, new_prev_type): 代码行列表和更新后的前一个 await 变量信息
        """
        generator = get_global_generator()
        code_lines = []

        prev_await_result_var = gen_ctx.prev_await_result_var
        prev_await_result_type = gen_ctx.prev_await_result_type

        # 先处理前一个 await 的结果变量赋值
        if prev_await_result_var and prev_await_result_type:
            # 如果应该合并，await 结果获取和 return 语句在同一个 try 块中
            if should_merge_with_next is not None:
                # 生成 await 结果获取代码（不单独包装 try/catch）
                result_line = self._generate_await_result_var_assignment(
                    prev_await_result_var,
                    prev_await_result_type,
                    gen_ctx,
                    try_block_id=None,  # 不单独包装，后续一起包装
                )
                code_lines.extend(result_line)
            else:
                # 不在同一个 try 块中，单独处理
                try_block_id = None
                if gen_ctx.async_dataflow:
                    for unit in gen_ctx.async_dataflow.units:
                        if (
                            unit.variables_defined
                            and prev_await_result_var in unit.variables_defined
                        ):
                            try_block_id = unit.try_block_id
                            break

                result_lines = self._generate_await_result_var_assignment(
                    prev_await_result_var,
                    prev_await_result_type,
                    gen_ctx,
                    try_block_id=try_block_id,
                )
                code_lines.extend(result_lines)
            prev_await_result_var = None
            prev_await_result_type = None

        # 检查当前 return 语句是否在 try 块中，且该 try 块有 finally
        # 使用 finally_stack 获取上下文信息，避免递归检查 IR 节点
        finally_ctx = gen_ctx.context.finally_stack.current()
        try_block_id_with_finally = (
            finally_ctx.try_block_id if (finally_ctx and finally_ctx.is_async) else None
        )
        is_in_except_block = gen_ctx.context.get_extension_param(
            "in_except_block", False
        )
        # 如果 finally_ctx 存在，说明在 try 块中且有 finally
        # 如果 finally_ctx 不存在，说明不在 try 块中或没有 finally
        # 注意：如果 return 在 finally 块中，finally_stack 已经被 pop 了，所以 finally_ctx 为 None
        # 我们需要通过检查 statement_block_node 来判断是否在 finally 块中
        is_in_finally_block = False
        if gen_ctx.statement_block_node and gen_ctx.async_dataflow:
            # 检查当前语句块是否是某个 try 块的 finalbody
            for try_block_info in gen_ctx.async_dataflow.try_blocks:
                if (
                    try_block_info.try_node
                    and try_block_info.try_node.finalbody
                    and id(try_block_info.try_node.finalbody)
                    == id(gen_ctx.statement_block_node)
                ):
                    is_in_finally_block = True
                    break

        # 生成 return 语句
        # 注意：如果 return 在 except 块中，不应该包装在 try 块中，但仍需要跳转到 finally（如果有）
        # 注意：如果 return 在 finally 块中，应该直接 return，而不是跳转到 finally 块（避免死循环）
        if (
            try_block_id_with_finally is not None
            and not is_in_finally_block
            and finally_ctx
        ):
            # 在 try 块中且有 finally，需要保存返回值并跳转到 finally 块
            # 但如果 return 本身就在 finally 块中，应该直接 return
            return_lines = []
            if stmt.expr:
                ret_code = generator.generate_expression(stmt.expr, gen_ctx.context)
                # 保存返回值
                return_lines.append(
                    f"{gen_ctx.indent}{finally_ctx.return_value_var} = {ret_code};"
                )
            # 设置 return 标志并跳转到 finally
            return_lines.append(f"{gen_ctx.indent}{finally_ctx.has_return_var} = true;")
            return_lines.append(f"{gen_ctx.indent}goto {finally_ctx.finally_label};")

            # 如果 return 在 except 块中，不需要包装在 try 块中
            if is_in_except_block:
                # except 块内的 return，直接添加代码，不包装 try/catch
                code_lines.extend(return_lines)
            else:
                # try 块内的 return，需要包装在 try 块中，避免跳转绕过变量初始化
                # 注意：如果 should_merge_with_next 不为 None，说明 await 结果获取和 return 应该在同一个 try 块中
                if (
                    should_merge_with_next is not None
                    and should_merge_with_next == try_block_id_with_finally
                ):
                    # await 结果获取和 return 在同一个 try 块中，一起包装
                    # code_lines 中已经包含了 await 结果获取代码（不包装 try/catch）
                    merged_lines = code_lines + return_lines
                    wrapped = self._wrap_with_try_catch(
                        merged_lines,
                        try_block_id_with_finally,
                        gen_ctx.indent,
                    )
                    code_lines = wrapped
                else:
                    # 单独包装 return 代码
                    # 但如果 await 结果获取代码已经生成（code_lines 不为空），也需要一起包装
                    if code_lines:
                        # await 结果获取代码已经生成，需要一起包装
                        merged_lines = code_lines + return_lines
                        wrapped = self._wrap_with_try_catch(
                            merged_lines,
                            try_block_id_with_finally,
                            gen_ctx.indent,
                        )
                        code_lines = wrapped
                    else:
                        # 只有 return 代码，单独包装
                        wrapped = self._wrap_with_try_catch(
                            return_lines,
                            try_block_id_with_finally,
                            gen_ctx.indent,
                        )
                        code_lines.extend(wrapped)
        elif try_block_id_with_finally is not None and is_in_finally_block:
            # 在 finally 块中的 return，直接 return（不跳转到 finally，避免死循环）
            # 但需要保存返回值，以便 finally 块后的代码能够使用
            # 注意：此时 finally_stack 已经被 pop，需要从外层 finally_ctx 获取信息
            outer_finally_ctx = gen_ctx.context.finally_stack.current()
            if (
                outer_finally_ctx
                and outer_finally_ctx.is_async
                and outer_finally_ctx.try_block_id == try_block_id_with_finally
            ):
                finally_ctx = outer_finally_ctx
            else:
                # 如果找不到外层 finally_ctx，回退到使用 try_block_id
                finally_ctx = None

            return_lines = []
            if stmt.expr:
                ret_code = generator.generate_expression(stmt.expr, gen_ctx.context)
                # 保存返回值
                if finally_ctx:
                    return_lines.append(
                        f"{gen_ctx.indent}{finally_ctx.return_value_var} = {ret_code};"
                    )
                    return_lines.append(
                        f"{gen_ctx.indent}{finally_ctx.has_return_var} = true;"
                    )
                    # 直接 return，不跳转到 finally（因为已经在 finally 块中）
                    return_lines.append(
                        f"{gen_ctx.indent}return set_result({finally_ctx.return_value_var});"
                    )
                else:
                    # 回退：使用 try_block_id
                    return_lines.append(
                        f"{gen_ctx.indent}__return_value_try_{try_block_id_with_finally} = {ret_code};"
                    )
                    return_lines.append(
                        f"{gen_ctx.indent}__has_return_try_{try_block_id_with_finally} = true;"
                    )
                    return_lines.append(
                        f"{gen_ctx.indent}return set_result(__return_value_try_{try_block_id_with_finally});"
                    )
            else:
                if finally_ctx:
                    return_lines.append(
                        f"{gen_ctx.indent}{finally_ctx.has_return_var} = true;"
                    )
                    return_lines.append(f"{gen_ctx.indent}return set_result();")
                else:
                    return_lines.append(
                        f"{gen_ctx.indent}__has_return_try_{try_block_id_with_finally} = true;"
                    )
                    return_lines.append(f"{gen_ctx.indent}return set_result();")
            code_lines.extend(return_lines)
        else:
            # 不在 try 块中或没有 finally，直接 return
            if stmt.expr:
                ret_code = generator.generate_expression(stmt.expr, gen_ctx.context)
                return_line = f"{gen_ctx.indent}return set_result({ret_code});"
            else:
                return_line = f"{gen_ctx.indent}return set_result();"

            # 如果应该合并，将 await 结果获取和 return 语句一起包装在 try 块中
            if should_merge_with_next is not None:
                # 合并 await 结果获取和 return 语句到同一个 try 块
                merged_lines = code_lines + [return_line]
                wrapped = self._wrap_with_try_catch(
                    merged_lines,
                    should_merge_with_next,
                    gen_ctx.indent,
                )
                code_lines = wrapped
            else:
                code_lines.append(return_line)

        return code_lines, prev_await_result_var, prev_await_result_type

    def _generate_remaining_await_result_var(
        self, gen_ctx: AsyncGenContext
    ) -> list[str]:
        """处理未消费的 await 结果变量（例如 if 分支末尾的 await）

        Args:
            gen_ctx: 异步代码生成上下文

        Returns:
            生成的代码行列表
        """
        prev_await_result_var = gen_ctx.prev_await_result_var
        prev_await_result_type = gen_ctx.prev_await_result_type

        if not prev_await_result_var or not prev_await_result_type:
            return []

        # 获取 try_block_id（从前一个 await 所在的 Unit）
        try_block_id = None
        prev_await_unit = getattr(gen_ctx, "prev_await_unit", None)
        if prev_await_unit:
            # 优先使用保存的前一个 await 所在的 unit
            try_block_id = prev_await_unit.try_block_id
        elif gen_ctx.async_dataflow:
            # 如果没有保存的 unit，尝试查找前一个 await 结果变量所在的 Unit
            for unit in gen_ctx.async_dataflow.units:
                if (
                    unit.variables_defined
                    and prev_await_result_var in unit.variables_defined
                ):
                    try_block_id = unit.try_block_id
                    break
            # 如果没找到（成员变量），查找包含 await 的 unit
            if try_block_id is None:
                # 查找最近的 has_await=True 的 unit
                for unit in reversed(gen_ctx.async_dataflow.units):
                    if unit.has_await:
                        try_block_id = unit.try_block_id
                        break

        # 判断后续代码是否还在同一个 try 块内
        # 在函数末尾，后续代码不在 try 块内了
        next_in_same_try_block = False
        return self._generate_await_result_var_assignment(
            prev_await_result_var,
            prev_await_result_type,
            gen_ctx,
            try_block_id=try_block_id,
            next_in_same_try_block=next_in_same_try_block,
        )

    def _handle_segment_start_empty_unit(
        self, segment, current_units, gen_ctx: AsyncGenContext
    ) -> tuple[list[str], Optional[str], Optional[str]]:
        """处理 Segment 开始位置的空单元（await 结果变量声明）

        Args:
            segment: 当前 Segment
            current_units: 当前语句块的 Units 列表
            gen_ctx: 异步代码生成上下文

        Returns:
            (code_lines, new_prev_var, new_prev_type): 代码行列表和更新后的前一个 await 变量信息
        """
        code_lines = []
        prev_await_result_var = gen_ctx.prev_await_result_var
        prev_await_result_type = gen_ctx.prev_await_result_type

        # 检查 Segment 开始位置是否有空的最小代码单元（用于 await 结果变量声明）
        for unit in current_units:
            if (
                unit.start_stmt_index != segment.start_stmt_index
                or unit.start_stmt_index != unit.end_stmt_index
                or not unit.variables_defined
            ):
                continue

            # 这是一个空单元，包含 await 结果变量的定义
            # 生成变量声明
            for var_name in unit.variables_defined:
                if prev_await_result_var != var_name or not prev_await_result_type:
                    continue

                # 获取 try_block_id
                try_block_id = unit.try_block_id if unit else None
                result_lines = self._generate_await_result_var_assignment(
                    var_name,
                    prev_await_result_type,
                    gen_ctx,
                    try_block_id=try_block_id,
                )
                code_lines.extend(result_lines)
                prev_await_result_var = None
                prev_await_result_type = None
                break

        return code_lines, prev_await_result_var, prev_await_result_type

    def _maybe_generate_prev_await_result(
        self,
        gen_ctx: AsyncGenContext,
        stmt,
        stmt_unit,
        units_need_defer,
        global_stmt_idx: Optional[int] = None,
    ) -> tuple[list[str], Optional[str], Optional[str], Optional[int]]:
        """在处理任何语句之前，可能需要生成前一个 await 的结果变量

        Args:
            gen_ctx: 异步代码生成上下文
            stmt: 当前语句
            stmt_unit: 语句所属的 Unit
            units_need_defer: 需要延迟生成的 unit_id 集合
            global_stmt_idx: 当前语句在全局的索引（用于查找前一个 await 语句）

        Returns:
            (code_lines, new_prev_var, new_prev_type, should_merge_with_next):
            代码行列表、更新后的前一个 await 变量信息、是否应该与下一个语句合并到同一个 try 块
        """
        code_lines = []
        prev_await_result_var = gen_ctx.prev_await_result_var
        prev_await_result_type = gen_ctx.prev_await_result_type
        should_merge_with_next = (
            None  # 如果为 None，表示不合并；如果为 try_block_id，表示应该合并
        )

        # 在处理任何语句之前，先处理前一个 await 的结果变量
        # 但如果当前 Unit 需要延迟生成，则不在这里生成（会在 co_yield 块中生成）
        # 注意：只有当是 await 赋值语句时才跳过（因为 await 赋值会在其他地方处理）
        # 普通赋值语句（如 total = total + val）应该被处理
        is_await_assign = (
            isinstance(stmt, IRAssign)
            and hasattr(stmt, "value")
            and isinstance(stmt.value, IRAwait)
        )

        if prev_await_result_var and not is_await_assign:
            # 检查当前 Unit 是否需要延迟生成
            should_defer_result_var = (
                stmt_unit and stmt_unit.unit_id in units_need_defer
            )

            if not should_defer_result_var and prev_await_result_type:
                # 不需要延迟，立即生成 await 结果变量
                # 获取 try_block_id（从前一个 await 所在的 Unit）
                prev_unit_try_block_id = None
                if gen_ctx.prev_await_unit:
                    # 直接使用保存的前一个 await 所在的 unit
                    prev_unit_try_block_id = gen_ctx.prev_await_unit.try_block_id
                elif gen_ctx.async_dataflow:
                    # 如果没有保存的 unit，尝试查找前一个 await 结果变量所在的 Unit
                    # 注意：对于成员变量，可能不在 variables_defined 中，需要查找包含 await 的 unit
                    for unit in gen_ctx.async_dataflow.units:
                        if (
                            unit.variables_defined
                            and prev_await_result_var in unit.variables_defined
                        ):
                            prev_unit_try_block_id = unit.try_block_id
                            break
                    # 如果没找到，尝试查找包含 await 的 unit（用于成员变量）
                    if prev_unit_try_block_id is None:
                        # 查找前一个 await 语句所在的 unit
                        # 通过遍历语句，找到前一个 await 语句，然后找到它所在的 unit
                        if global_stmt_idx is not None and hasattr(
                            gen_ctx, "statements"
                        ):
                            # 从当前语句向前查找，找到前一个 await 语句
                            for i in range(global_stmt_idx - 1, -1, -1):
                                if i >= len(gen_ctx.statements):
                                    continue
                                prev_stmt = gen_ctx.statements[i]
                                if isinstance(prev_stmt, IRAssign) and isinstance(
                                    prev_stmt.value, IRAwait
                                ):
                                    # 找到前一个 await 语句，查找它所在的 unit
                                    for unit in gen_ctx.async_dataflow.units:
                                        if (
                                            unit.start_stmt_index
                                            <= i
                                            < unit.end_stmt_index
                                            and unit.has_await
                                        ):
                                            prev_unit_try_block_id = unit.try_block_id
                                            break
                                    break
                        # 如果还是没找到，查找最近的 has_await=True 的 unit（fallback）
                        # 注意：对于成员变量，await 结果变量的赋值本质上属于前一个 await 所在的 try 块
                        if (
                            prev_unit_try_block_id is None
                            and gen_ctx.async_dataflow
                            and gen_ctx.async_dataflow.units
                        ):
                            # 查找最近的 has_await=True 的 unit
                            for unit in reversed(gen_ctx.async_dataflow.units):
                                if unit.has_await:
                                    prev_unit_try_block_id = unit.try_block_id
                                    break

                # 检查当前语句是否在同一个 try 块中
                current_stmt_try_block_id = (
                    stmt_unit.try_block_id if stmt_unit else None
                )

                # 如果 await 结果获取和当前语句在同一个 try 块中，标记为合并
                if (
                    prev_unit_try_block_id is not None
                    and prev_unit_try_block_id == current_stmt_try_block_id
                ):
                    # 在同一个 try 块中，不单独生成 try/catch，标记为合并
                    should_merge_with_next = prev_unit_try_block_id
                    # 不在这里生成，也不清除 prev_await_result_var，让后续语句生成时一起处理
                    # 注意：不要清除 prev_await_result_var，让 _generate_normal_statement 处理
                else:
                    # 不在同一个 try 块中，或者不在 try 块中，单独生成
                    # 注意：即使 current_stmt_try_block_id 为 None，如果 prev_unit_try_block_id 不为 None，
                    # 也应该使用 prev_unit_try_block_id，因为 await 结果变量的赋值本质上属于前一个 await 所在的 try 块
                    # 判断后续代码是否还在同一个 try 块内
                    # 如果当前语句也在同一个 try 块内，则后续代码还在同一个 try 块内
                    next_in_same_try_block = (
                        prev_unit_try_block_id is not None
                        and current_stmt_try_block_id is not None
                        and prev_unit_try_block_id == current_stmt_try_block_id
                    )
                    result_lines = self._generate_await_result_var_assignment(
                        prev_await_result_var,
                        prev_await_result_type,
                        gen_ctx,
                        try_block_id=prev_unit_try_block_id,
                        next_in_same_try_block=next_in_same_try_block,
                    )
                    code_lines.extend(result_lines)
                    prev_await_result_var = None
                    prev_await_result_type = None

        return (
            code_lines,
            prev_await_result_var,
            prev_await_result_type,
            should_merge_with_next,
        )

    def _generate_statements_in_co_yield_block(
        self, unit_stmts: list, gen_ctx: AsyncGenContext, block_indent: str
    ) -> list[str]:
        """在 co_yield 块中生成 await 之前的所有语句

        Args:
            unit_stmts: Unit 中 await 之前的语句列表
            gen_ctx: 异步代码生成上下文
            block_indent: co_yield 块的缩进

        Returns:
            生成的代码行列表
        """
        generator = get_global_generator()
        code_lines = []

        for unit_stmt in unit_stmts:
            # 生成每条语句
            if isinstance(unit_stmt, IRAssign) and not isinstance(
                unit_stmt.value, IRAwait
            ):
                # 检查是否是元组解包赋值
                if (
                    hasattr(unit_stmt, "is_tuple_unpacking")
                    and unit_stmt.is_tuple_unpacking
                ):
                    # 元组解包：使用正常的语句生成流程
                    stmt_code = generator.generate_statement(unit_stmt, gen_ctx.context)
                    if stmt_code and not stmt_code.isspace():
                        code_lines.append(f"{block_indent}{stmt_code}")
                    continue

                # 单目标赋值
                target = unit_stmt.get_target_expr()
                if not target or not isinstance(target, IRName):
                    # 不是简单的单目标赋值，使用正常的语句生成流程
                    stmt_code = generator.generate_statement(unit_stmt, gen_ctx.context)
                    if stmt_code and not stmt_code.isspace():
                        code_lines.append(f"{block_indent}{stmt_code}")
                    continue

                var_name = target.id
                if var_name in gen_ctx.state_vars or var_name in gen_ctx.header_vars:
                    # 成员变量或函数头变量：只生成赋值
                    value_code = generator.generate_expression(
                        unit_stmt.value, gen_ctx.context
                    )
                    code_lines.append(f"{block_indent}{var_name} = {value_code};")
                else:
                    # 局部变量：生成声明和赋值
                    var_type = target.get_extension_param("cpp_type", "mc::variant")
                    value_code = generator.generate_expression(
                        unit_stmt.value, gen_ctx.context
                    )
                    code_lines.append(
                        f"{block_indent}{var_type} {var_name} = {value_code};"
                    )
            elif isinstance(unit_stmt, IRForRange):
                # for 循环：手动生成
                loop_var = (
                    unit_stmt.var.id
                    if isinstance(unit_stmt.var, IRName)
                    else str(unit_stmt.var)
                )
                start_code = generator.generate_expression(
                    unit_stmt.start, gen_ctx.context
                )
                end_code = generator.generate_expression(unit_stmt.end, gen_ctx.context)
                step_code = (
                    generator.generate_expression(unit_stmt.step, gen_ctx.context)
                    if unit_stmt.step
                    else "1"
                )
                need_decl = (
                    loop_var not in gen_ctx.state_vars
                    and loop_var not in gen_ctx.header_vars
                )
                if need_decl:
                    code_lines.append(
                        f"{block_indent}for (int {loop_var} = {start_code}; {loop_var} < {end_code}; {loop_var} += {step_code}) {{"
                    )
                else:
                    code_lines.append(f"{block_indent}{loop_var} = {start_code};")
                    code_lines.append(
                        f"{block_indent}for (; {loop_var} < {end_code}; {loop_var} += {step_code}) {{"
                    )
                # 生成循环体
                if unit_stmt.body:
                    body_ctx = gen_ctx.with_statement_block(unit_stmt.body).with_indent(
                        block_indent + "    "
                    )
                    body_lines = self.generate_async_statements(body_ctx)
                    code_lines.extend(body_lines)
                code_lines.append(f"{block_indent}}}")
            elif isinstance(unit_stmt, IRWhile):
                # while 循环：手动生成
                cond_code = generator.generate_expression(
                    unit_stmt.test, gen_ctx.context
                )
                code_lines.append(f"{block_indent}while ({cond_code}) {{")
                if unit_stmt.body:
                    body_ctx = gen_ctx.with_statement_block(unit_stmt.body).with_indent(
                        block_indent + "    "
                    )
                    body_lines = self.generate_async_statements(body_ctx)
                    code_lines.extend(body_lines)
                code_lines.append(f"{block_indent}}}")
            elif isinstance(unit_stmt, IRIf):
                # if 语句：手动生成
                cond_code = generator.generate_expression(
                    unit_stmt.test, gen_ctx.context
                )
                code_lines.append(f"{block_indent}if ({cond_code}) {{")
                if unit_stmt.then_body:
                    then_ctx = gen_ctx.with_statement_block(
                        unit_stmt.then_body
                    ).with_indent(block_indent + "    ")
                    then_lines = self.generate_async_statements(then_ctx)
                    code_lines.extend(then_lines)
                if unit_stmt.else_body:
                    code_lines.append(f"{block_indent}}} else {{")
                    else_ctx = gen_ctx.with_statement_block(
                        unit_stmt.else_body
                    ).with_indent(block_indent + "    ")
                    else_lines = self.generate_async_statements(else_ctx)
                    code_lines.extend(else_lines)
                code_lines.append(f"{block_indent}}}")
            else:
                # 其他类型的语句（如 IRExprStmt 表达式语句）使用通用的语句生成器
                stmt_code = generator.generate_statement(unit_stmt, gen_ctx.context)
                if stmt_code and not stmt_code.isspace():
                    code_lines.append(f"{block_indent}{stmt_code}")

        return code_lines

    def _generate_local_var_definitions_in_co_yield(
        self, unit_stmts: list, gen_ctx: AsyncGenContext, block_indent: str
    ) -> list[str]:
        """在 co_yield 块中生成局部变量定义（不需要延迟的 Unit）

        Args:
            unit_stmts: Unit 中 await 之前的语句列表
            gen_ctx: 异步代码生成上下文
            block_indent: co_yield 块的缩进

        Returns:
            生成的代码行列表
        """
        generator = get_global_generator()
        code_lines = []

        for unit_stmt in unit_stmts:
            if not isinstance(unit_stmt, IRAssign):
                continue

            target = unit_stmt.get_target_expr()
            if not target or not isinstance(target, IRName):
                continue

            var_name = target.id
            if var_name in gen_ctx.state_vars or var_name in gen_ctx.header_vars:
                continue

            is_decl = unit_stmt.get_extension_param("is_variable_declaration", True)
            if not is_decl:
                continue

            # 生成局部变量定义
            var_type = target.get_extension_param("cpp_type", "mc::variant")
            value_code = generator.generate_expression(unit_stmt.value, gen_ctx.context)
            code_lines.append(f"{block_indent}{var_type} {var_name} = {value_code};")

        return code_lines

    def _generate_co_yield_block(
        self,
        gen_ctx: AsyncGenContext,
        await_expr_code: str,
        stmt_unit,
        global_stmt_idx: int,
        units_need_defer: set,
    ) -> tuple[list[str], Optional[str], Optional[str]]:
        """生成完整的 co_yield { ... } 块（情况3）

        Args:
            gen_ctx: 异步代码生成上下文
            await_expr_code: await 表达式代码
            stmt_unit: 语句所属的 Unit
            global_stmt_idx: await 语句在全局的索引
            units_need_defer: 需要延迟生成的 unit_id 集合

        Returns:
            (code_lines, new_prev_var, new_prev_type): 代码行列表和更新后的前一个 await 变量信息
        """
        code_lines = []
        # 根据是否在 try 块中决定使用 co_yield { 还是 co_yield try {
        try_block_id = None
        if stmt_unit and stmt_unit.try_block_id is not None:
            try_block_id = stmt_unit.try_block_id
            code_lines.append(f"{gen_ctx.indent}co_yield try {{")
        else:
            code_lines.append(f"{gen_ctx.indent}co_yield {{")
        block_indent = gen_ctx.indent + "    "

        prev_await_result_var = gen_ctx.prev_await_result_var
        prev_await_result_type = gen_ctx.prev_await_result_type

        # 设置标志：我们在 co_yield 块中，break/continue 应该使用 co_break/co_continue
        gen_ctx.context.set_extension_param("in_co_yield_block", True)

        # 生成前一个 await 的结果变量赋值
        if prev_await_result_var and prev_await_result_type:
            gen_ctx_block = gen_ctx.with_indent(block_indent)
            # 获取 try_block_id（从前一个 await 所在的 Unit）
            prev_try_block_id = None
            if gen_ctx.async_dataflow:
                for unit in gen_ctx.async_dataflow.units:
                    if (
                        unit.variables_defined
                        and prev_await_result_var in unit.variables_defined
                    ):
                        prev_try_block_id = unit.try_block_id
                        break

            # 判断后续代码是否还在同一个 try 块内
            # 注意：在 co_yield try 块之后，获取 __resume_value 的代码虽然在 try 块内，
            # 但后续代码（异常处理标签之后）不在 try 块内了，所以 next_in_same_try_block 应该是 False
            # 只有在 co_yield try 块之前获取 __resume_value 时，才可能 next_in_same_try_block 为 True
            # 但这里是在 co_yield try 块之后，所以 next_in_same_try_block 应该是 False
            next_in_same_try_block = False
            result_lines = self._generate_await_result_var_assignment(
                prev_await_result_var,
                prev_await_result_type,
                gen_ctx_block,
                try_block_id=prev_try_block_id,
                next_in_same_try_block=next_in_same_try_block,
            )
            code_lines.extend(result_lines)
            prev_await_result_var = None
            prev_await_result_type = None

        # 生成当前单元中 await 之前的所有语句
        # 如果 unit 在 units_need_defer 中，说明它有 await 且有局部变量定义（情况3）
        # 需要生成整个 unit 的所有语句
        if stmt_unit and stmt_unit.unit_id in units_need_defer:
            unit_stmts = gen_ctx.statements[
                stmt_unit.start_stmt_index : global_stmt_idx
            ]
            if unit_stmts:
                gen_ctx_block = gen_ctx.with_indent(block_indent)
                lines = self._generate_statements_in_co_yield_block(
                    unit_stmts,
                    gen_ctx_block,
                    block_indent=block_indent,
                )
                code_lines.extend(lines)

        # 生成 await 调用
        # 检查是否有 parent_try_block_id（即是否是嵌套的内层 try 块）
        parent_try_id = stmt_unit.parent_try_block_id if stmt_unit else None

        if try_block_id is not None and parent_try_id is not None:
            # 嵌套 try 块：使用简化的单层 co_yield try
            # co_catch 会路由到正确的 co_except，在那里构造异常处理链
            code_lines.append(f"{block_indent}return await({await_expr_code}, __ctx);")
            code_lines.append(
                f"{gen_ctx.indent}}} co_catch({try_block_id}, CO_CLEAR_STATE);"
            )
            code_lines.append("")  # 空行，提高可读性
        elif try_block_id is not None:
            # 非嵌套 try 块
            code_lines.append(f"{block_indent}return await({await_expr_code}, __ctx);")
            code_lines.append(
                f"{gen_ctx.indent}}} co_catch({try_block_id}, CO_CLEAR_STATE);"
            )
            code_lines.append("")  # 空行，提高可读性
        else:
            # 不在 try 块中
            code_lines.append(f"{block_indent}return await({await_expr_code}, __ctx);")
            code_lines.append(f"{gen_ctx.indent}}}")

        # 清除标志：退出 co_yield 块
        gen_ctx.context.set_extension_param(
            "in_co_yield_block", False, replace_existing=True
        )

        return code_lines, prev_await_result_var, prev_await_result_type

    def _generate_try_except_statement(
        self,
        stmt: IRTryExcept,
        gen_ctx: AsyncGenContext,
        stmt_unit=None,
    ) -> tuple[list[str], Optional[str], Optional[str]]:
        """生成 try/except/finally 语句代码（异步版本）

        Args:
            stmt: try/except 语句节点
            gen_ctx: 异步代码生成上下文
            stmt_unit: 语句所属的 Unit

        Returns:
            (code_lines, new_prev_var, new_prev_type): 代码行列表和更新后的前一个 await 变量信息
        """
        code_lines = []
        prev_await_result_var = gen_ctx.prev_await_result_var
        prev_await_result_type = gen_ctx.prev_await_result_type

        # 查找对应的 try_block_info
        try_block_info = None
        if gen_ctx.async_dataflow:
            for tb_info in gen_ctx.async_dataflow.try_blocks:
                if tb_info.try_node == stmt:
                    try_block_info = tb_info
                    break

        if not try_block_info:
            # 如果没有找到 try_block_info，说明这个 try 块不包含 await
            # 使用普通的代码生成（不添加异常处理）
            generator = get_global_generator()
            stmt_code = generator.generate_statement(stmt, gen_ctx.context)
            if stmt_code and not stmt_code.isspace():
                code_lines.append(f"{gen_ctx.indent}{stmt_code}")
            return code_lines, prev_await_result_var, prev_await_result_type

        try_id = try_block_info.try_block_id
        indent = gen_ctx.indent

        # 如果 try 块在循环中，需要重置异常和控制流标志变量
        # 这样每次循环迭代都从干净的状态开始
        if try_block_info.in_loop:
            code_lines.append(f"{indent}__exception_ptr_try_{try_id} = nullptr;")
            if try_block_info.has_else:
                code_lines.append(f"{indent}__no_exception_try_{try_id} = true;")
            if try_block_info.has_finally:
                code_lines.append(f"{indent}__has_return_try_{try_id} = false;")
                code_lines.append(f"{indent}__has_break_try_{try_id} = false;")
                code_lines.append(f"{indent}__has_continue_try_{try_id} = false;")

        # 如果有 finally 块，在 try 块生成之前就 push finally_ctx 到栈中
        # 这样 try 块中的 break/continue/return 就能正确跳转到 finally
        finally_ctx = None
        if try_block_info.has_finally:  # ✅ 直接从 try_block_info 中读取
            # 创建并压入 finally 上下文到栈（在生成 try 块之前）
            from mcpy.codegen.finally_context import FinallyContext

            # 获取函数返回类型
            ret_val_type_from_ctx = gen_ctx.context.get_extension_param("ret_val_type")
            return_type = ret_val_type_from_ctx if ret_val_type_from_ctx else "void"

            finally_ctx = FinallyContext(
                label=f"__try_{try_id}_finally",
                suffix="",  # 异步代码不使用 suffix
                return_type=return_type,
                has_else=try_block_info.has_else,  # ✅ 直接从 try_block_info 中读取
                in_loop=try_block_info.in_loop,  # ✅ 直接从 try_block_info 中读取
                try_block_id=try_id,
                is_async=True,
            )
            gen_ctx.context.finally_stack.push(finally_ctx)

        # 如果有 else 子句，初始化标志变量（在 try 块开始前）
        if try_block_info.has_else:  # ✅ 直接从 try_block_info 中读取
            code_lines.append(f"{indent}__no_exception_try_{try_id} = true;")

        # 用于跟踪 try 块内未处理的 await 结果变量
        try_block_prev_await_result_var = None
        try_block_prev_await_result_type = None
        try_block_prev_await_unit = None

        try:
            # 递归生成 try 块内的语句
            # 关键：try块内的语句会根据各自的unit.try_block_id独立添加try包裹
            # 不需要在这里整体包裹
            if stmt.body:
                try_ctx = gen_ctx.with_statement_block(stmt.body)
                try_lines = self.generate_async_statements(try_ctx)
                # ✅ 直接添加，不做额外包裹（每个unit已经根据其try_block_id包裹了）
                code_lines.extend(try_lines)
                # 保存 try 块内未处理的 await 结果变量
                try_block_prev_await_result_var = try_ctx.prev_await_result_var
                try_block_prev_await_result_type = try_ctx.prev_await_result_type
                try_block_prev_await_unit = getattr(try_ctx, "prev_await_unit", None)
        finally:
            # 如果 finally_ctx 被 push 了，现在先不 pop，等到 finally 块生成完成后再 pop
            # 注意：这里不 pop，因为 finally 块还需要使用这个上下文
            pass

        # 检查当前 try 块是否有 parent_try_block_id（即是否是嵌套的内层 try 块）
        parent_try_id = try_block_info.parent_try_block_id

        # 在生成异常检查标签之前，处理 try 块内未处理的 await 结果变量
        # 注意：try 块内的 await 结果变量应该在 try 块结束后、异常处理标签之前生成
        # 如果是嵌套 try 块，获取 await 结果的代码应该被外层 try 包裹
        if try_block_prev_await_result_var and try_block_prev_await_result_type:
            # 有未处理的 await 结果变量，需要在异常处理标签之前生成
            prev_try_block_id = (
                try_block_prev_await_unit.try_block_id
                if try_block_prev_await_unit
                else None
            )
            # 判断后续代码是否还在同一个 try 块内
            # 在 try 块结束后，后续代码（异常处理标签之后）不在 try 块内了
            next_in_same_try_block = False
            result_lines = self._generate_await_result_var_assignment(
                try_block_prev_await_result_var,
                try_block_prev_await_result_type,
                gen_ctx,
                try_block_id=prev_try_block_id,
                next_in_same_try_block=next_in_same_try_block,
            )
            code_lines.extend(result_lines)

            # 更新 prev_await_result_var，以便后续代码使用
            prev_await_result_var = try_block_prev_await_result_var
            prev_await_result_type = try_block_prev_await_result_type

        # 生成异常检查标签（使用 co_except 宏）
        code_lines.append("")  # 空行，分隔异常处理代码
        code_lines.append(f"{indent}co_except({try_id})")

        # 生成 except 处理器
        # 如果是嵌套 try 块，异常处理逻辑应该被外层 try 包裹
        except_handler_lines = []
        if try_block_info.has_except_handlers:  # ✅ 直接从 try_block_info 中读取
            # 检查异常指针是否为 nullptr，如果是则跳过异常处理
            # 所有 except 子句应该在一个 try 块中，使用连续的 catch 子句
            # 使用 co_rethrow 宏重新抛出异常
            except_handler_lines.append(f"{indent}    co_rethrow({try_id})")

            # 生成所有 catch 子句
            for handler in stmt.handlers:
                # 获取 C++ 异常类型
                cpp_exception_type = self._get_exception_cpp_type(
                    handler.type, gen_ctx.context
                )
                exc_var_name = handler.exception_name if handler.exception_name else ""

                # 生成 catch 子句
                # 注意：co_rethrow 宏已经包含了 try { ... }，所以这里只需要 catch
                if cpp_exception_type is None:
                    # bare except: 捕获所有异常
                    except_handler_lines.append(f"{indent}        catch (...) {{")
                else:
                    # 特定异常类型
                    except_handler_lines.append(
                        f"{indent}        catch (const {cpp_exception_type}& {exc_var_name}) {{"
                    )
                # 清空异常指针，因为异常已经被处理了，不会再重新抛出
                except_handler_lines.append(
                    f"{indent}            __exception_ptr_try_{try_id} = nullptr;"
                )
                # 如果有 else 子句，设置标志变量为 false（表示有异常发生）
                if try_block_info.has_else:  # ✅ 直接从 try_block_info 中读取
                    except_handler_lines.append(
                        f"{indent}            __no_exception_try_{try_id} = false;"
                    )

                # 生成 except 块内的语句
                if handler.body:
                    handler_ctx = gen_ctx.with_statement_block(handler.body)
                    # 标记当前在 except 块中，break/continue 应该使用普通的 break/continue 而不是 co_break/co_continue
                    handler_ctx.context.set_extension_param("in_except_block", True)
                    handler_ctx = handler_ctx.with_indent(indent + "            ")
                    handler_lines = self.generate_async_statements(handler_ctx)
                    handler_ctx.context.set_extension_param("in_except_block", False)
                    except_handler_lines.extend(handler_lines)

                # 闭合当前 catch 子句（除了最后一个）
                # 注意：最后一个 catch 子句后面需要闭合整个 try 块
                if handler != stmt.handlers[-1]:
                    except_handler_lines.append(f"{indent}        }}")

            # 闭合最后一个 catch 子句和整个 try 块
            except_handler_lines.append(f"{indent}        }}")

        # 如果是嵌套 try 块，异常处理逻辑应该被外层 try 包裹
        if parent_try_id is not None and except_handler_lines:
            code_lines.append(f"{indent}try {{")
            code_lines.extend(except_handler_lines)
            code_lines.append(f"{indent}}} co_catch({parent_try_id}, CO_CLEAR_STATE);")
            code_lines.append("")  # 空行
        elif except_handler_lines:
            code_lines.append(f"{indent} {{")
            code_lines.extend(except_handler_lines)
            code_lines.append(f"{indent}}}")
            code_lines.append("")  # 空行
        else:
            # 没有 except 处理器，生成空块
            # 这是必需的，因为 co_except 宏包含 if 条件，必须有对应的语句块
            code_lines.append(f"{indent} {{}}")
            code_lines.append("")  # 空行

        # 生成 else 子句（在 except 之后、finally 之前）
        # 如果是嵌套 try 块，else 块应该被外层 try 包裹
        # 注意：else 块生成时，finally_ctx 仍然在栈中（确保 raise 语句能正确跳转到 finally）
        if try_block_info.has_else:  # ✅ 直接从 try_block_info 中读取
            # 生成 else 块内容
            else_ctx = gen_ctx.with_statement_block(stmt.orelse)
            else_content_lines = self.generate_async_statements(else_ctx)

            # 使用 co_except_else 宏，参考 co_except 的代码生成逻辑
            code_lines.append(f"{indent}co_except_else({try_id})")

            # 如果是嵌套 try 块且 else 块不为空，用外层 try 包裹
            if parent_try_id is not None and else_content_lines:
                code_lines.append(f"{indent}try {{")
                code_lines.extend(else_content_lines)
                code_lines.append(
                    f"{indent}}} co_catch({parent_try_id}, CO_CLEAR_STATE);"
                )
                code_lines.append("")  # 空行
            elif else_content_lines:
                # 不是嵌套 try，直接输出 else 块内容
                code_lines.append(f"{indent}{{")
                code_lines.extend(else_content_lines)
                code_lines.append(f"{indent}}}")
                code_lines.append("")  # 空行
            else:
                # else 块为空，生成空块
                code_lines.append(f"{indent} {{}}")
                code_lines.append("")  # 空行

        # 生成 finally 块
        # 如果是嵌套 try 块，finally 块应该被外层 try 包裹
        if try_block_info.has_finally:  # ✅ 直接从 try_block_info 中读取
            code_lines.append(f"{indent}co_finally({try_id})")

            # finally_ctx 已经在 try 块生成之前被 push 到栈中了
            # 在生成 finally 块代码之前，先弹出 finally 上下文
            # 这样 finally 块内部的 return/break/continue 就不会再 goto finally
            # 注意：这里先 pop，这样 finally 块中的 break/continue 就能正确判断 is_in_finally_block
            if finally_ctx:
                gen_ctx.context.finally_stack.pop()

            # 收集 finally 块及其后续控制流代码
            finally_block_lines = []

            # 生成 finally 块代码
            final_ctx = gen_ctx.with_statement_block(stmt.finalbody)
            final_lines = self.generate_async_statements(final_ctx)
            finally_block_lines.extend(final_lines)

            # finally 块后，检查是否需要 return
            # 如果 __has_return_try_{try_id} 为 true，调用 set_result 并 return
            # 获取函数返回类型（从 gen_ctx.context 中获取）
            func_node = gen_ctx.context.get_extension_param("current_node")
            if not func_node:
                # 如果 context 中没有，尝试从 statement_block_node 向上查找
                node = gen_ctx.statement_block_node
                while node and not isinstance(node, IRFunctionNode):
                    if hasattr(node, "parent"):
                        node = node.parent
                    else:
                        node = None
                if node:
                    func_node = node

            # 检查返回类型是否为 void
            # 注意：对于异步函数，需要检查 ret_val_type（从 generate_coro_body 参数获取）
            # 而不是 cpp_return_type（可能是 mc::result<void>）
            is_void_return = False
            # 尝试从 context 中获取 ret_val_type
            ret_val_type_from_ctx = gen_ctx.context.get_extension_param("ret_val_type")
            if ret_val_type_from_ctx:
                is_void_return = ret_val_type_from_ctx == "void"
            elif func_node:
                # 如果没有 ret_val_type，尝试从 cpp_return_type 推断
                ret_type = func_node.get_extension_param("cpp_return_type")
                if ret_type:
                    # 从 mc::result<T> 中提取 T
                    import re

                    m = re.match(r"mc::result<\s*(.+)\s*>", ret_type)
                    if m:
                        ret_val_type_inferred = m.group(1)
                        is_void_return = ret_val_type_inferred == "void"
                    elif ret_type == "void":
                        is_void_return = True

            # finally 块后，先检查异常，如果有异常则重新抛出
            # 注意：异常检查应该在 return/break/continue 检查之前，因为如果有异常，不应该 return/break/continue
            finally_block_lines.append(f"{indent}if (__exception_ptr_try_{try_id}) {{")
            finally_block_lines.append(
                f"{indent}    std::rethrow_exception(__exception_ptr_try_{try_id});"
            )
            finally_block_lines.append(f"{indent}}}")
            # finally 块中的控制流（break/continue）应该优先执行，覆盖 except 中的控制流
            # 所以先检查 finally 块中是否有 break/continue（通过检查 finally 块执行后的状态）
            # 注意：finally 块中的 break/continue 会直接执行，不会设置 __has_break_try_X/__has_continue_try_X
            # 只有在 except 块中设置的 break/continue 才会设置这些标志
            # 所以这里的逻辑是：如果 except 中设置了 break/continue，但 finally 中没有执行 break/continue，
            # 则执行 except 中的 break/continue
            # 但实际上，finally 中的 break/continue 会直接执行，不会到达这里
            # 所以这里的检查顺序是正确的：先检查 break，再检查 continue，最后检查 return
            # 检查是否有外层 finally（用于后续 break/continue/return 传递）
            has_parent_finally = False
            if parent_try_id is not None and gen_ctx.async_dataflow:
                for parent_try_info in gen_ctx.async_dataflow.try_blocks:
                    if parent_try_info.try_block_id == parent_try_id:
                        has_parent_finally = parent_try_info.has_finally
                        break

            # 生成 break 检查代码（在 return 之前，因为 break 优先级更高）
            finally_block_lines.append(f"{indent}if (__has_break_try_{try_id}) {{")
            if has_parent_finally:
                # 有外层 finally，传递 break 到外层
                finally_block_lines.append(
                    f"{indent}    __has_break_try_{parent_try_id} = true;"
                )
                finally_block_lines.append(
                    f"{indent}    goto __try_{parent_try_id}_finally;"
                )
            else:
                # 没有外层 finally，直接 break
                finally_block_lines.append(f"{indent}    co_break;")
            finally_block_lines.append(f"{indent}}}")

            # 生成 continue 检查代码（在 return 之前，因为 continue 优先级更高）
            finally_block_lines.append(f"{indent}if (__has_continue_try_{try_id}) {{")
            if has_parent_finally:
                # 有外层 finally，传递 continue 到外层
                finally_block_lines.append(
                    f"{indent}    __has_continue_try_{parent_try_id} = true;"
                )
                finally_block_lines.append(
                    f"{indent}    goto __try_{parent_try_id}_finally;"
                )
            else:
                # 没有外层 finally，直接 continue
                finally_block_lines.append(f"{indent}    co_continue;")
            finally_block_lines.append(f"{indent}}}")
            # 生成 return 检查代码
            # 注意：如果有外层 finally，内层 finally 的 return 应该传递到外层 finally
            # 如果没有外层 finally，才直接 return
            finally_block_lines.append(f"{indent}if (__has_return_try_{try_id}) {{")
            if has_parent_finally:
                # 有外层 finally，传递 return 到外层
                if not is_void_return:
                    finally_block_lines.append(
                        f"{indent}    __return_value_try_{parent_try_id} = __return_value_try_{try_id};"
                    )
                finally_block_lines.append(
                    f"{indent}    __has_return_try_{parent_try_id} = true;"
                )
                finally_block_lines.append(
                    f"{indent}    goto __try_{parent_try_id}_finally;"
                )
            else:
                # 没有外层 finally，直接 return
                if is_void_return:
                    finally_block_lines.append(f"{indent}    return set_result();")
                else:
                    finally_block_lines.append(
                        f"{indent}    return set_result(__return_value_try_{try_id});"
                    )
            finally_block_lines.append(f"{indent}}}")

            # 如果是嵌套 try 块，finally 块应该被外层 try 包裹
            if parent_try_id is not None:
                code_lines.append(f"{indent}try {{")
                code_lines.extend(finally_block_lines)
                code_lines.append(
                    f"{indent}}} co_catch({parent_try_id}, CO_CLEAR_STATE);"
                )
                code_lines.append("")  # 空行
            else:
                code_lines.extend(finally_block_lines)

        return code_lines, prev_await_result_var, prev_await_result_type

    def _generate_normal_statement(
        self,
        stmt,
        gen_ctx: AsyncGenContext,
        stmt_unit=None,
        global_stmt_idx: Optional[int] = None,
        units_need_defer: Optional[set] = None,
        should_defer_to_co_yield: bool = False,
        should_merge_with_next: Optional[int] = None,
    ) -> tuple[list[str], Optional[str], Optional[str]]:
        """生成普通语句代码

        Args:
            stmt: 当前语句
            gen_ctx: 异步代码生成上下文
            stmt_unit: 语句所属的 Unit
            global_stmt_idx: 语句在全局的索引
            units_need_defer: 需要延迟生成的 unit_id 集合
            should_defer_to_co_yield: 是否应该延迟到 co_yield 块
            should_merge_with_next: 如果为 try_block_id，表示应该与 await 结果获取合并到同一个 try 块

        Returns:
            (code_lines, new_prev_var, new_prev_type): 代码行列表和更新后的前一个 await 变量信息
        """
        generator = get_global_generator()
        code_lines = []
        await_result_lines = []  # 用于存储 await 结果获取代码（如果需要合并）

        prev_await_result_var = gen_ctx.prev_await_result_var
        prev_await_result_type = gen_ctx.prev_await_result_type

        # 先处理前一个 await 的结果变量赋值
        # 但是：如果当前单元包含 await，并且 prev_await_result_var 是局部变量，
        # 则不应该在这里生成，而应该在后续的 co_yield 块中生成
        if prev_await_result_var:
            should_generate_here = True

            # 检查是否应该延迟到 co_yield 块中生成
            # 优先检查 Unit 是否需要延迟生成
            if stmt_unit and units_need_defer and stmt_unit.unit_id in units_need_defer:
                # Unit 需要延迟生成，不在这里生成 await 结果变量
                should_generate_here = False
            elif (
                global_stmt_idx is not None
                and prev_await_result_var not in gen_ctx.state_vars
                and prev_await_result_var not in gen_ctx.header_vars
                and stmt_unit
                and stmt_unit.has_await
            ):
                # 局部变量，并且当前单元包含 await
                # 检查是否有后续的 await 语句
                for next_stmt_idx in range(global_stmt_idx, stmt_unit.end_stmt_index):
                    if next_stmt_idx >= len(gen_ctx.statements):
                        continue

                    next_stmt = gen_ctx.statements[next_stmt_idx]
                    if not isinstance(next_stmt, IRAssign) or not isinstance(
                        next_stmt.value, IRAwait
                    ):
                        continue

                    # 有后续的 await，延迟到 co_yield 块中生成
                    should_generate_here = False
                    break

            if should_generate_here and prev_await_result_type:
                # 如果应该合并，先保存到 await_result_lines，后续一起处理
                if should_merge_with_next is not None:
                    # should_merge_with_next 不为 None 表示后续代码应该合并到同一个 try 块中
                    result_lines = self._generate_await_result_var_assignment(
                        prev_await_result_var,
                        prev_await_result_type,
                        gen_ctx,
                        try_block_id=None,  # 不单独包装，后续一起包装
                        next_in_same_try_block=True,  # 后续代码在同一个 try 块内
                    )
                    await_result_lines.extend(result_lines)
                else:
                    # 不在同一个 try 块中，单独处理
                    try_block_id = None
                    # 优先使用保存的前一个 await 所在的 unit
                    if hasattr(gen_ctx, "prev_await_unit") and gen_ctx.prev_await_unit:
                        try_block_id = gen_ctx.prev_await_unit.try_block_id
                    elif gen_ctx.async_dataflow:
                        # 查找包含变量的 unit
                        for unit in gen_ctx.async_dataflow.units:
                            if (
                                unit.variables_defined
                                and prev_await_result_var in unit.variables_defined
                            ):
                                try_block_id = unit.try_block_id
                                break
                        # 如果没找到（成员变量），查找前一个 await 所在的 unit
                        if try_block_id is None:
                            # 查找最近的 has_await=True 的 unit
                            for unit in reversed(gen_ctx.async_dataflow.units):
                                if unit.has_await:
                                    try_block_id = unit.try_block_id
                                    break

                    # 判断后续代码是否还在同一个 try 块内
                    # 如果当前语句也在同一个 try 块内，则后续代码还在同一个 try 块内
                    next_in_same_try_block = bool(
                        try_block_id is not None
                        and stmt_unit
                        and stmt_unit.try_block_id is not None
                        and try_block_id == stmt_unit.try_block_id
                    )
                    result_lines = self._generate_await_result_var_assignment(
                        prev_await_result_var,
                        prev_await_result_type,
                        gen_ctx,
                        try_block_id=try_block_id,
                        next_in_same_try_block=next_in_same_try_block,
                    )
                    code_lines.extend(result_lines)
                prev_await_result_var = None
                prev_await_result_type = None

        # 如果语句需要延迟，跳过生成
        if should_defer_to_co_yield:
            return code_lines, prev_await_result_var, prev_await_result_type

        # 跳过嵌套函数定义语句（已经在 co_reenter 之前声明了）
        from mcpy.ir.declarations.function import IRFunctionNode

        if isinstance(stmt, IRFunctionNode):
            # 嵌套函数定义已经在 co_reenter 之前声明，这里不需要生成代码
            return code_lines, prev_await_result_var, prev_await_result_type

        # 生成语句代码（根据 try_block_id 添加异常处理）
        stmt_code_lines = []

        # 生成语句代码（根据 try_block_id 添加异常处理）
        stmt_code_lines = []

        # 检查是否是成员变量/函数头变量的赋值
        if isinstance(stmt, IRAssign):
            target = stmt.get_target_expr()
            if target and isinstance(target, IRName):
                var_name = target.id
                if var_name in gen_ctx.state_vars or var_name in gen_ctx.header_vars:
                    # 只生成赋值，不生成类型声明
                    value_code = generator.generate_expression(
                        stmt.value, gen_ctx.context
                    )
                    stmt_code_lines.append(
                        f"{gen_ctx.indent}{var_name} = {value_code};"
                    )
                else:
                    # 正常生成语句
                    # 检查是否是变量声明（如 else_executed = False）
                    # 如果是变量声明且在 co_reenter 块内，应该被提升为函数头变量
                    var_name = target.id if target else None

                    # 检查是否是变量声明（首次赋值，可能是变量声明）
                    # 如果变量不在 header_vars 或 state_vars 中，且是首次赋值，可能是变量声明
                    is_potential_var_decl = (
                        var_name
                        and var_name not in gen_ctx.state_vars
                        and var_name not in gen_ctx.header_vars
                    )

                    # 如果变量应该在函数头声明，但当前在 co_reenter 块内，只生成赋值
                    if var_name and var_name in gen_ctx.header_vars:
                        # 变量已在函数头声明，只生成赋值
                        value_code = generator.generate_expression(
                            stmt.value, gen_ctx.context
                        )
                        stmt_code_lines.append(
                            f"{gen_ctx.indent}{var_name} = {value_code};"
                        )
                    else:
                        # 正常生成语句
                        stmt_code = generator.generate_statement(stmt, gen_ctx.context)
                        if stmt_code and not stmt_code.isspace():
                            stmt_code_lines.append(f"{gen_ctx.indent}{stmt_code}")
            else:
                # 正常生成语句
                stmt_code = generator.generate_statement(stmt, gen_ctx.context)
                if stmt_code and not stmt_code.isspace():
                    stmt_code_lines.append(f"{gen_ctx.indent}{stmt_code}")
        else:
            # 检查是否是 break/continue 语句，这些语句不应该被包装在 try/catch 中
            from mcpy.ir.statements.control import IRBreak, IRContinue

            if isinstance(stmt, (IRBreak, IRContinue)):
                # break/continue 语句：直接生成，不包装在 try/catch 中
                in_except_block = gen_ctx.context.get_extension_param(
                    "in_except_block", False
                )
                if in_except_block:
                    # 在 except 块中，需要检查是否有 finally
                    # 如果有 finally，应该设置标志并跳转到 finally
                    # 如果没有 finally，使用普通的 break/continue
                    # 查找当前 except 块所属的 try 块
                    current_try_block_id = None
                    if gen_ctx.async_dataflow and gen_ctx.statement_block_node:
                        # 查找包含当前语句块的 try 块
                        for try_block_info in gen_ctx.async_dataflow.try_blocks:
                            if try_block_info.try_node:
                                # 检查当前语句块是否在某个 except handler 中
                                for handler in try_block_info.try_node.handlers:
                                    if handler.body and id(handler.body) == id(
                                        gen_ctx.statement_block_node
                                    ):
                                        # 找到了包含当前 except 块的 try 块
                                        current_try_block_id = (
                                            try_block_info.try_block_id
                                        )
                                        # 检查是否有 finally
                                        if try_block_info.try_node.finalbody:
                                            # 有 finally，设置标志并跳转
                                            if isinstance(stmt, IRBreak):
                                                stmt_code_lines.append(
                                                    f"{gen_ctx.indent}__has_break_try_{current_try_block_id} = true;"
                                                )
                                            else:  # IRContinue
                                                stmt_code_lines.append(
                                                    f"{gen_ctx.indent}__has_continue_try_{current_try_block_id} = true;"
                                                )
                                            stmt_code_lines.append(
                                                f"{gen_ctx.indent}goto __try_{current_try_block_id}_finally;"
                                            )
                                        else:
                                            # 没有 finally，使用普通的 break/continue
                                            if isinstance(stmt, IRBreak):
                                                stmt_code_lines.append(
                                                    f"{gen_ctx.indent}break;"
                                                )
                                            else:  # IRContinue
                                                stmt_code_lines.append(
                                                    f"{gen_ctx.indent}continue;"
                                                )
                                        break
                                if current_try_block_id is not None:
                                    break

                    # 如果没有找到 try 块，使用普通的 break/continue
                    if current_try_block_id is None:
                        if isinstance(stmt, IRBreak):
                            stmt_code_lines.append(f"{gen_ctx.indent}break;")
                        else:  # IRContinue
                            stmt_code_lines.append(f"{gen_ctx.indent}continue;")
                else:
                    # 检查 break/continue 是否在 try 块中，且该 try 块有 finally
                    # 使用 finally_stack 获取上下文信息，避免递归检查 IR 节点
                    finally_ctx = gen_ctx.context.finally_stack.current()
                    try_block_id_with_finally = (
                        finally_ctx.try_block_id
                        if (finally_ctx and finally_ctx.is_async)
                        else None
                    )

                    # 检查是否在 finally 块中
                    # 注意：在 finally 块中，finally_stack 已经被 pop，所以 finally_ctx 为 None
                    # 但我们仍然可以通过 statement_block_node 来判断是否在 finally 块中
                    is_in_finally_block = False
                    if gen_ctx.statement_block_node and gen_ctx.async_dataflow:
                        # 检查当前语句块是否是某个 try 块的 finalbody
                        for try_block_info in gen_ctx.async_dataflow.try_blocks:
                            if (
                                try_block_info.try_node
                                and try_block_info.try_node.finalbody
                                and id(try_block_info.try_node.finalbody)
                                == id(gen_ctx.statement_block_node)
                            ):
                                is_in_finally_block = True
                                break

                    # 只有在 try 块中且有 finally，且不在 finally 块中，且 finally_ctx 存在时，才跳转到 finally
                    # 如果 finally_ctx 为 None（说明在 finally 块中，栈已被 pop），不应该跳转
                    if (
                        try_block_id_with_finally is not None
                        and not is_in_finally_block
                        and finally_ctx is not None
                    ):
                        # 在 try 块中且有 finally，需要跳转到 finally 块
                        if isinstance(stmt, IRBreak):
                            # 设置 break 标志，跳转到 finally
                            stmt_code_lines.append(
                                f"{gen_ctx.indent}{finally_ctx.should_break_var} = true;"
                            )
                            stmt_code_lines.append(
                                f"{gen_ctx.indent}goto {finally_ctx.finally_label};"
                            )
                        else:  # IRContinue
                            # 设置 continue 标志，跳转到 finally
                            stmt_code_lines.append(
                                f"{gen_ctx.indent}{finally_ctx.should_continue_var} = true;"
                            )
                            stmt_code_lines.append(
                                f"{gen_ctx.indent}goto {finally_ctx.finally_label};"
                            )
                    else:
                        # 不在 try 块中或没有 finally，或者已经在 finally 块中，直接 break/continue
                        if isinstance(stmt, IRBreak):
                            stmt_code_lines.append(f"{gen_ctx.indent}co_break;")
                        else:  # IRContinue
                            # 在 finally 块中，continue 应该清除 break 标志（因为 continue 覆盖 break）
                            if is_in_finally_block:
                                # 找到当前 finally 块所属的 try 块
                                current_finally_try_id = None
                                if (
                                    gen_ctx.async_dataflow
                                    and gen_ctx.statement_block_node
                                ):
                                    for (
                                        try_block_info
                                    ) in gen_ctx.async_dataflow.try_blocks:
                                        if (
                                            try_block_info.try_node
                                            and try_block_info.try_node.finalbody
                                            and id(try_block_info.try_node.finalbody)
                                            == id(gen_ctx.statement_block_node)
                                        ):
                                            current_finally_try_id = (
                                                try_block_info.try_block_id
                                            )
                                            break
                                if current_finally_try_id is not None:
                                    # 清除 break 标志，因为 continue 覆盖 break
                                    stmt_code_lines.append(
                                        f"{gen_ctx.indent}__has_break_try_{current_finally_try_id} = false;"
                                    )
                            stmt_code_lines.append(f"{gen_ctx.indent}co_continue;")
            else:
                # 检查是否是 raise 语句，需要特殊处理
                from mcpy.ir.statements import IRRaise

                if isinstance(stmt, IRRaise):
                    # raise 语句在 except 块或 else 块中需要传播到外层 try 块
                    in_except_block = gen_ctx.context.get_extension_param(
                        "in_except_block", False
                    )
                    # 检查是否在 else 块中
                    in_else_block = False
                    if gen_ctx.async_dataflow and gen_ctx.statement_block_node:
                        for try_block_info in gen_ctx.async_dataflow.try_blocks:
                            if (
                                try_block_info.try_node
                                and try_block_info.try_node.orelse
                                and id(try_block_info.try_node.orelse)
                                == id(gen_ctx.statement_block_node)
                            ):
                                in_else_block = True
                                break
                    if in_except_block or in_else_block:
                        # 在 except 块或 else 块中，需要找到当前 try 块和外层 try 块
                        current_try_block_id = None
                        current_try_block_info = None

                        if gen_ctx.async_dataflow and gen_ctx.statement_block_node:
                            # 首先找到包含当前 except/else 块的 try 块
                            for try_block_info in gen_ctx.async_dataflow.try_blocks:
                                if try_block_info.try_node:
                                    # 检查当前语句块是否在某个 except handler 中
                                    for handler in try_block_info.try_node.handlers:
                                        if handler.body and id(handler.body) == id(
                                            gen_ctx.statement_block_node
                                        ):
                                            # 找到了包含当前 except 块的 try 块
                                            current_try_block_id = (
                                                try_block_info.try_block_id
                                            )
                                            current_try_block_info = try_block_info
                                            break
                                    # 检查当前语句块是否在 else 块中
                                    if (
                                        current_try_block_id is None
                                        and try_block_info.try_node.orelse
                                        and id(try_block_info.try_node.orelse)
                                        == id(gen_ctx.statement_block_node)
                                    ):
                                        # 找到了包含当前 else 块的 try 块
                                        current_try_block_id = (
                                            try_block_info.try_block_id
                                        )
                                        current_try_block_info = try_block_info
                                    if current_try_block_id is not None:
                                        break

                        # 决定跳转目标：
                        # - else 块中的 raise：应该跳转到当前 try 块的 finally（如果有）或 外层 try 块
                        # - except 块中的 raise：应该跳转到外层 try 块
                        target_try_block_id = None

                        if in_else_block and current_try_block_info:
                            # else 块中的 raise：应该先执行当前 try 块的 finally
                            if current_try_block_info.has_finally:
                                # 当前 try 块有 finally，跳转到当前 try 块的 finally
                                target_try_block_id = current_try_block_id
                            else:
                                # 当前 try 块没有 finally，跳转到外层 try 块
                                target_try_block_id = (
                                    current_try_block_info.parent_try_block_id
                                )
                        elif in_except_block and current_try_block_info:
                            # except 块中的 raise：跳转到外层 try 块
                            target_try_block_id = (
                                current_try_block_info.parent_try_block_id
                            )

                        # 如果找到了目标 try 块，设置异常并跳转
                        if target_try_block_id is not None:
                            # 查找目标 try 块信息
                            target_try_block_info = None
                            if gen_ctx.async_dataflow:
                                for try_block_info in gen_ctx.async_dataflow.try_blocks:
                                    if (
                                        try_block_info.try_block_id
                                        == target_try_block_id
                                    ):
                                        target_try_block_info = try_block_info
                                        break

                            if stmt.exc is None:
                                # bare raise: 重新抛出当前异常
                                stmt_code_lines.append(
                                    f"{gen_ctx.indent}__exception_ptr_try_{target_try_block_id} = std::current_exception();"
                                )
                            else:
                                # raise with exception: 生成异常表达式并设置
                                exc_code = generator.generate_expression(
                                    stmt.exc, gen_ctx.context
                                )
                                stmt_code_lines.append(
                                    f"{gen_ctx.indent}__exception_ptr_try_{target_try_block_id} = std::make_exception_ptr({exc_code});"
                                )

                            # 检查目标 try 块是否有 finally
                            if (
                                target_try_block_info
                                and target_try_block_info.has_finally
                            ):
                                stmt_code_lines.append(
                                    f"{gen_ctx.indent}goto __try_{target_try_block_id}_finally;"
                                )
                            else:
                                stmt_code_lines.append(
                                    f"{gen_ctx.indent}goto __try_{target_try_block_id}_catch_check;"
                                )
                        else:
                            # 没有找到外层 try 块，使用普通的 throw
                            stmt_code = generator.generate_statement(
                                stmt, gen_ctx.context
                            )
                            if stmt_code and not stmt_code.isspace():
                                stmt_code_lines.append(f"{gen_ctx.indent}{stmt_code}")
                    else:
                        # 不在 except 块中，使用普通的代码生成
                        stmt_code = generator.generate_statement(stmt, gen_ctx.context)
                        if stmt_code and not stmt_code.isspace():
                            stmt_code_lines.append(f"{gen_ctx.indent}{stmt_code}")
                else:
                    # 正常生成语句
                    stmt_code = generator.generate_statement(stmt, gen_ctx.context)
                    if stmt_code and not stmt_code.isspace():
                        stmt_code_lines.append(f"{gen_ctx.indent}{stmt_code}")

        # 如果应该合并，将 await 结果获取和语句代码一起包装在 try 块中
        # 注意：合并时，await 结果获取和后续语句必须在同一个作用域中
        # 但是 break/continue 语句不应该被包装在 try/catch 中
        from mcpy.ir.statements.control import IRBreak, IRContinue

        is_break_or_continue = isinstance(stmt, (IRBreak, IRContinue))

        if (
            should_merge_with_next is not None
            and await_result_lines
            and not is_break_or_continue
        ):
            # 合并 await 结果获取和语句代码到同一个 try 块
            # 不添加额外的块作用域，避免局部变量作用域问题
            merged_lines = []
            merged_lines.extend(await_result_lines)
            merged_lines.extend(stmt_code_lines)

            wrapped = self._wrap_with_try_catch(
                merged_lines,
                should_merge_with_next,
                gen_ctx.indent,
            )
            code_lines.extend(wrapped)
        else:
            # 不合并，分别处理
            code_lines.extend(await_result_lines)
            # break/continue 语句不应该被包装在 try/catch 中
            if is_break_or_continue:
                code_lines.extend(stmt_code_lines)
            else:
                # 检查当前语句是否在 finally 块中
                is_in_finally = False
                if gen_ctx.async_dataflow and gen_ctx.statement_block_node:
                    # 检查当前语句块是否是某个 try 块的 finalbody
                    for try_block_info in gen_ctx.async_dataflow.try_blocks:
                        if (
                            try_block_info.try_node
                            and try_block_info.try_node.finalbody
                            and id(try_block_info.try_node.finalbody)
                            == id(gen_ctx.statement_block_node)
                        ):
                            is_in_finally = True
                            break
                # 检查当前语句是否在 except 块中
                is_in_except_block = gen_ctx.context.get_extension_param(
                    "in_except_block", False
                )
                # 根据 Unit 的 try_block_id 添加异常处理
                # 注意：finally 块和 except 块内的语句不应该被包装在 try 块中
                # - finally 块本身就在 try 块之外
                # - except 块内的代码已经在异常处理上下文中，不需要额外的 try 包装
                if (
                    stmt_unit
                    and stmt_unit.try_block_id is not None
                    and stmt_code_lines
                    and not is_in_finally
                    and not is_in_except_block
                ):
                    wrapped = self._wrap_with_try_catch(
                        stmt_code_lines,
                        stmt_unit.try_block_id,
                        gen_ctx.indent,
                    )
                    code_lines.extend(wrapped)
                else:
                    code_lines.extend(stmt_code_lines)

        return code_lines, prev_await_result_var, prev_await_result_type

    def generate_coro_body(
        self,
        node,
        ret_val_type: str,
        context: CodeGenContext,
    ) -> str:
        """生成协程状态机的函数体

        规则：
        1) 按 await 分段；2) 判断是否有局部声明与是否以 await 结束；
        3) 代码生成：
           - 有声明+以 await 结束 → co_yield { ... }
           - 有声明+非 await 结束 → { ... }
           - 无声明+以 await 结束 → co_yield_return await(...);
           - 无声明+非 await 结束 → 直接生成

        Args:
            node: 函数节点
            ret_val_type: 返回值类型
            context: 代码生成上下文
            captures: 捕获的变量列表
            params: 函数参数列表
            struct_name: 结构体名称

        Returns:
            生成的协程体代码
        """
        generator = get_global_generator()
        statements = node.body.statements if node.body else []

        code_parts = []

        # 获取数据流分析结果
        async_dataflow = node.get_extension_param("async_dataflow")
        if not async_dataflow:
            raise RuntimeError("async_dataflow not found for async function")

        # 使用新的数据流分析结果
        state_vars = {var: None for var in async_dataflow.member_variables}
        header_vars = set(async_dataflow.header_variables)
        has_any_await = any(unit.has_await for unit in async_dataflow.units)

        # 生成函数签名
        code_parts.append(
            f"""
    mc::result<{ret_val_type}> execute(resume_value_type& __resume_value, mcpy::async_context& __ctx) {{"""
        )

        # 如果没有 await，直接执行代码（不使用协程）
        if not has_any_await:
            for stmt in statements:
                stmt_code = generator.generate_statement(stmt, context)
                if stmt_code and not stmt_code.isspace():
                    code_parts.append(f"        {stmt_code}")
            code_parts.append("        return set_result();")
            code_parts.append("    }")
            return "\n".join(code_parts)

        # 生成函数头变量声明
        if async_dataflow and async_dataflow.header_variables:
            for var_name in sorted(async_dataflow.header_variables):
                # 从 IR 推断类型
                var_type = get_local_var_type(statements, var_name, context)

                if not var_type:
                    # 如果 get_local_var_type 找不到类型，尝试从 promotion_info 中获取
                    promotion_info = async_dataflow.variable_promotions.get(var_name)
                    if promotion_info:
                        # 优先使用已经转换好的 cpp_type（类型替换阶段的结果）
                        # 尝试从 ir_node 获取
                        if promotion_info.ir_node:
                            var_type = promotion_info.ir_node.get_extension_param(
                                "cpp_type"
                            )

                        # 如果 ir_node 没有 cpp_type，尝试从 init_expr 获取（对于外部变量）
                        if not var_type and promotion_info.init_expr:
                            var_type = promotion_info.init_expr.get_extension_param(
                                "cpp_type"
                            )

                        # 如果还是没有 cpp_type，从 type_info 转换
                        if not var_type and promotion_info.type_info:
                            from mcpy.type_system import get_cpp_type

                            var_type = get_cpp_type(
                                promotion_info.type_info, promotion_info.ir_node
                            )
                    if not var_type:
                        if var_name == "result":
                            var_type = ret_val_type
                        else:
                            var_type = "mc::variant"
                code_parts.append(f"        {var_type} {var_name};")

        # 收集嵌套函数定义语句，根据数据流分析结果决定是 member 还是 header
        # 这样可以避免在 switch 语句中定义变量（C++ 不允许变量初始化跨越 case 标签）
        from mcpy.ir.declarations.function import IRFunctionNode
        from mcpy.codegen.emitters.nested_function.utils import get_functor_name

        # 只收集应该作为 header 变量的嵌套函数（不跨 await 的）
        # 跨 await 的嵌套函数应该作为 member 变量（在 struct 中生成）
        nested_function_header_vars = []
        for stmt in statements:
            if isinstance(stmt, IRFunctionNode):
                # 这是嵌套函数定义语句
                func_var_name = stmt.name

                # 检查数据流分析结果：如果是 member 变量，跳过（已在 struct 中生成）
                if async_dataflow and func_var_name in async_dataflow.member_variables:
                    # 嵌套函数变量跨 await 使用，应该作为 member 变量，跳过
                    continue

                # 检查是否是简单函数（无捕获），简单函数不生成 header 变量声明
                # 它们将在调用处通过临时对象调用生成
                is_simple = stmt.get_extension_param("is_simple_non_capturing", False)
                if not is_simple:
                    # 如果标记未设置，检查 captured_vars 是否为空
                    captured_vars = stmt.captured_vars or []
                    is_simple = len(captured_vars) == 0

                if is_simple:
                    # 简单函数不生成 header 变量声明，完全通过 call_emitter 在调用处生成临时对象调用
                    continue

                # 否则，作为 header 变量（在 co_reenter 之前声明）
                functor_name = get_functor_name(stmt)
                captured_vars = stmt.captured_vars or []
                storage_mode = stmt.get_extension_param("storage_mode", "stack")

                if storage_mode == "heap":
                    # 堆模式：mc::variant var_name = mc::variant(mc::make_shared<functor>(...));
                    if captured_vars:
                        captures = ", ".join(captured_vars)
                        var_decl = f"mc::variant {func_var_name} = mc::variant(mc::make_shared<{functor_name}>({captures}));"
                    else:
                        var_decl = f"mc::variant {func_var_name} = mc::variant(mc::make_shared<{functor_name}>());"
                else:
                    # 栈模式：functor var_name(...);
                    if captured_vars:
                        captures = ", ".join(captured_vars)
                        var_decl = f"{functor_name} {func_var_name}({captures});"
                    else:
                        var_decl = f"{functor_name} {func_var_name};"

                nested_function_header_vars.append((func_var_name, var_decl))

        # 在 co_reenter 之前生成嵌套函数变量声明（只包括 header 变量）
        for var_name, var_decl in nested_function_header_vars:
            code_parts.append(f"        {var_decl}")

        # 生成异常状态变量声明
        if async_dataflow and async_dataflow.try_blocks:
            for try_block_info in async_dataflow.try_blocks:
                try_id = try_block_info.try_block_id
                code_parts.append(
                    f"        std::exception_ptr __exception_ptr_try_{try_id} = nullptr;"
                )
                # 如果 try 块有 else 子句，需要声明标志变量
                if try_block_info.try_node.orelse:
                    code_parts.append(
                        f"        bool __no_exception_try_{try_id} = true;"
                    )
                # 如果 try 块有 finally，需要声明 return/break/continue 相关变量
                if try_block_info.try_node.finalbody:
                    code_parts.append(
                        f"        bool __has_return_try_{try_id} = false;"
                    )
                    code_parts.append(f"        bool __has_break_try_{try_id} = false;")
                    code_parts.append(
                        f"        bool __has_continue_try_{try_id} = false;"
                    )
                    if ret_val_type and ret_val_type != "void":
                        code_parts.append(
                            f"        {ret_val_type} __return_value_try_{try_id}{{}};"
                        )

        code_parts.append("        co_reenter(this) {")

        if async_dataflow:
            # 将 ret_val_type 设置到 context 中，供 finally 块使用
            context.set_extension_param(
                "ret_val_type", ret_val_type, replace_existing=True
            )
            gen_ctx = AsyncGenContext(
                context=context,
                statements=statements,
                state_vars=state_vars,
                header_vars=header_vars,
                async_dataflow=async_dataflow,
                statement_block_node=node.body,
                indent="            ",
            )
            body_lines = self.generate_async_statements(gen_ctx)
            code_parts.extend(body_lines)

            # 关闭 co_reenter 块
            code_parts.append("        }")
            code_parts.append("        return set_result(__resume_value);")
            code_parts.append("    }")
            return "\n".join(code_parts)

        # 如果没有 async_dataflow，返回错误
        raise RuntimeError("async_dataflow not found for async function")

    def generate_async_statements(self, gen_ctx: AsyncGenContext) -> list[str]:
        """递归生成异步语句，基于最小代码单元

        Args:
            gen_ctx: 异步代码生成上下文

        Returns:
            生成的代码行列表
        """
        code_lines = []

        # 1. 初始化：找到当前 Segments 和 Units
        current_segments, current_units = self._find_current_segments_and_units(
            gen_ctx.async_dataflow, gen_ctx.statement_block_node
        )

        # 2. 处理简单情况（无 Segments）
        if not current_segments:
            return self._handle_no_segments_case(gen_ctx)

        # 3. 预处理：判断哪些 Unit 需要延迟生成
        units_need_defer = self._identify_units_need_defer(current_units, gen_ctx)

        # 按 Segment 遍历生成代码
        prev_await_result_var = None
        prev_await_result_type = None

        for seg_idx, segment in enumerate(current_segments):
            # 获取此 Segment 的所有语句
            seg_stmts = gen_ctx.statements[
                segment.start_stmt_index : segment.end_stmt_index
            ]

            if not seg_stmts:
                continue

            # 处理 Segment 开始位置的空单元
            # 更新上下文中的 await 结果变量
            gen_ctx_with_await = gen_ctx.with_await_result(
                prev_await_result_var, prev_await_result_type, None
            )
            lines, prev_await_result_var, prev_await_result_type = (
                self._handle_segment_start_empty_unit(
                    segment,
                    current_units,
                    gen_ctx_with_await,
                )
            )
            code_lines.extend(lines)

            # 遍历 Segment 中的每条语句
            for stmt_idx_in_seg, stmt in enumerate(seg_stmts):
                global_stmt_idx = segment.start_stmt_index + stmt_idx_in_seg

                # 查找这条语句属于哪个最小代码单元
                stmt_unit = self._find_stmt_unit(global_stmt_idx, current_units)

                # 处理前一个 await 的结果变量（如果需要）
                # 更新上下文中的 await 结果变量，确保传递 prev_await_unit
                # 注意：gen_ctx 可能在循环中被更新（保存了 prev_await_unit），所以要使用最新的 gen_ctx
                prev_await_unit = getattr(gen_ctx, "prev_await_unit", None)
                gen_ctx_with_await = gen_ctx.with_await_result(
                    prev_await_result_var, prev_await_result_type, prev_await_unit
                )
                (
                    lines,
                    prev_await_result_var,
                    prev_await_result_type,
                    should_merge_with_next,
                ) = self._maybe_generate_prev_await_result(
                    gen_ctx_with_await,
                    stmt=stmt,
                    stmt_unit=stmt_unit,
                    units_need_defer=units_need_defer,
                    global_stmt_idx=global_stmt_idx,
                )
                code_lines.extend(lines)

                # 处理不同类型的语句
                # 判断当前语句是否应该延迟到 co_yield 块中生成
                should_defer_to_co_yield = self._should_defer_statement_to_co_yield(
                    stmt, stmt_unit, global_stmt_idx, gen_ctx, units_need_defer
                )

                if isinstance(stmt, IRIf):
                    lines = self._generate_if_statement(
                        stmt,
                        gen_ctx,
                        should_defer=should_defer_to_co_yield,
                    )
                    code_lines.extend(lines)

                elif isinstance(stmt, IRForRange):
                    lines = self._generate_for_range_statement(
                        stmt,
                        gen_ctx,
                        should_defer=should_defer_to_co_yield,
                    )
                    code_lines.extend(lines)

                elif isinstance(stmt, IRWhile):
                    lines = self._generate_while_statement(
                        stmt,
                        gen_ctx,
                        should_defer=should_defer_to_co_yield,
                    )
                    code_lines.extend(lines)

                elif isinstance(stmt, IRAssign) and isinstance(stmt.value, IRAwait):
                    # await 语句：使用 Minimal Unit 信息确定 co_yield 形式

                    # 获取 await 结果变量和类型
                    await_target = stmt.get_target_expr()
                    await_result_var = (
                        await_target.id
                        if await_target and isinstance(await_target, IRName)
                        else None
                    )
                    await_result_type = (
                        get_await_result_type(stmt.value) or "mc::variant"
                    )

                    # 生成 await 表达式代码
                    await_expr_code = self._generate_await_expression_code(
                        stmt, gen_ctx.context, gen_ctx.statement_block_node
                    )

                    # 判断是否需要 co_yield 块
                    gen_ctx_with_await = gen_ctx.with_await_result(
                        prev_await_result_var, prev_await_result_type
                    )
                    use_co_yield_block = self._should_use_co_yield_block(
                        gen_ctx_with_await,
                        stmt_unit=stmt_unit,
                        global_stmt_idx=global_stmt_idx,
                        units_need_defer=units_need_defer,
                    )

                    if use_co_yield_block:
                        # 情况3：co_yield { ... }
                        gen_ctx_with_await = gen_ctx.with_await_result(
                            prev_await_result_var, prev_await_result_type, None
                        )
                        lines, prev_await_result_var, prev_await_result_type = (
                            self._generate_co_yield_block(
                                gen_ctx_with_await,
                                await_expr_code=await_expr_code,
                                stmt_unit=stmt_unit,
                                global_stmt_idx=global_stmt_idx,
                                units_need_defer=units_need_defer,
                            )
                        )
                        code_lines.extend(lines)
                    else:
                        # 情况2：co_yield_return await(...)
                        gen_ctx_with_await = gen_ctx.with_await_result(
                            prev_await_result_var, prev_await_result_type, None
                        )
                        lines, prev_await_result_var, prev_await_result_type = (
                            self._generate_co_yield_return(
                                gen_ctx_with_await,
                                await_expr_code=await_expr_code,
                                stmt_unit=stmt_unit,
                            )
                        )
                        code_lines.extend(lines)
                        # 注意：这里不更新 gen_ctx，因为 await_result_var 还没有被赋值给 prev_await_result_var

                    # 保存当前 await 的结果变量信息和所在的 unit，供下一条语句使用
                    # 只有当 await_result_var 不是 None 且不是 "_" 时才保存
                    if await_result_var and await_result_var != "_":
                        prev_await_result_var = await_result_var
                        prev_await_result_type = await_result_type
                        # 更新 gen_ctx，保存当前 await 所在的 unit（用于后续查找 try_block_id）
                        gen_ctx = gen_ctx.with_await_result(
                            prev_await_result_var, prev_await_result_type, stmt_unit
                        )
                    else:
                        prev_await_result_var = None
                        prev_await_result_type = None
                        gen_ctx = gen_ctx.with_await_result(None, None, None)

                elif isinstance(stmt, IRReturn):
                    # 更新上下文中的 await 结果变量
                    gen_ctx_with_await = gen_ctx.with_await_result(
                        prev_await_result_var, prev_await_result_type
                    )
                    lines, prev_await_result_var, prev_await_result_type = (
                        self._generate_return_statement(
                            stmt,
                            gen_ctx_with_await,
                            should_merge_with_next=should_merge_with_next,
                        )
                    )
                    code_lines.extend(lines)

                elif isinstance(stmt, IRTryExcept):
                    # try/except/finally 语句：递归处理
                    gen_ctx_with_await = gen_ctx.with_await_result(
                        prev_await_result_var, prev_await_result_type
                    )
                    lines, prev_await_result_var, prev_await_result_type = (
                        self._generate_try_except_statement(
                            stmt,
                            gen_ctx_with_await,
                            stmt_unit=stmt_unit,
                        )
                    )
                    code_lines.extend(lines)
                else:
                    # 确保传递 prev_await_unit
                    prev_await_unit = getattr(gen_ctx, "prev_await_unit", None)
                    gen_ctx_with_await = gen_ctx.with_await_result(
                        prev_await_result_var, prev_await_result_type, prev_await_unit
                    )
                    lines, prev_await_result_var, prev_await_result_type = (
                        self._generate_normal_statement(
                            stmt,
                            gen_ctx_with_await,
                            stmt_unit=stmt_unit,
                            global_stmt_idx=global_stmt_idx,
                            units_need_defer=units_need_defer,
                            should_defer_to_co_yield=should_defer_to_co_yield,
                            should_merge_with_next=should_merge_with_next,
                        )
                    )
                    code_lines.extend(lines)

        # 处理未消费的 await 结果变量（例如 if 分支末尾的 await）
        gen_ctx_with_await = gen_ctx.with_await_result(
            prev_await_result_var, prev_await_result_type
        )
        remaining_lines = self._generate_remaining_await_result_var(
            gen_ctx_with_await,
        )
        code_lines.extend(remaining_lines)

        # 后处理：合并连续的同try_block_id的try块
        merged_lines = self._merge_consecutive_try_blocks(code_lines)

        return merged_lines

    def _merge_consecutive_try_blocks(self, code_lines: list[str]) -> list[str]:
        """合并连续的同try_block_id的try块

        将形如：
            try { stmt1; } co_catch(0);
            try { stmt2; } co_catch(0);
        合并为：
            try { stmt1; stmt2; } co_catch(0);

        但保留co_yield try块和不同try_block_id的try块。

        Args:
            code_lines: 原始代码行列表

        Returns:
            合并后的代码行列表
        """
        if not code_lines:
            return code_lines

        result = []
        i = 0

        while i < len(code_lines):
            line = code_lines[i]
            stripped = line.strip()

            # 检测普通try块的开始（不是co_yield try）
            if stripped == "try {":
                # 确认前一行不是co_yield
                is_co_yield_try = i > 0 and "co_yield" in code_lines[i - 1]

                if not is_co_yield_try:
                    # 普通try块，尝试合并
                    indent = line[: len(line) - len(line.lstrip())]
                    try_end, try_block_id = self._find_try_block_end(code_lines, i)

                    if try_end and try_block_id is not None:
                        # 收集所有连续的同try_block_id的try块
                        all_inner_lines = []
                        current_pos = i

                        while True:
                            # 提取当前try块的内容
                            inner_lines = code_lines[current_pos + 1 : try_end]
                            all_inner_lines.extend(inner_lines)

                            # 查找下一个try块
                            next_pos = try_end + 1
                            # 跳过空行
                            while (
                                next_pos < len(code_lines)
                                and not code_lines[next_pos].strip()
                            ):
                                next_pos += 1

                            if next_pos < len(code_lines):
                                next_line = code_lines[next_pos].strip()
                                
                                # 检查是否是 co_yield try（可能在一行或两行）
                                next_is_co_yield = False
                                co_yield_line_idx = -1
                                try_line_idx = -1
                                
                                if "co_yield" in next_line and "try {" in next_line:
                                    # co_yield try { 在同一行
                                    next_is_co_yield = True
                                    co_yield_line_idx = next_pos
                                    try_line_idx = next_pos
                                elif "co_yield" in next_line:
                                    # co_yield 单独一行，检查下一行是否是 try {
                                    if next_pos + 1 < len(code_lines) and code_lines[next_pos + 1].strip() == "try {":
                                        next_is_co_yield = True
                                        co_yield_line_idx = next_pos
                                        try_line_idx = next_pos + 1
                                        next_pos = next_pos + 1
                                        next_line = "try {"

                                if next_line == "try {" or (next_is_co_yield and try_line_idx >= 0):
                                    if next_is_co_yield:
                                        # co_yield try 块，检查 try_block_id 是否相同
                                        next_end, next_try_id = self._find_try_block_end(
                                            code_lines, try_line_idx
                                        )
                                        
                                        if next_end and next_try_id == try_block_id:
                                            # 同 try_block_id，将前面累积的代码合并到 co_yield 块中
                                            result.append(code_lines[co_yield_line_idx])  # co_yield (或 co_yield try {)
                                            if co_yield_line_idx != try_line_idx:
                                                result.append(code_lines[try_line_idx])  # try {（如果是分开的）
                                            result.extend(all_inner_lines)  # 前面累积的代码
                                            # 添加 co_yield 块的剩余内容
                                            for j in range(try_line_idx + 1, next_end + 1):
                                                result.append(code_lines[j])
                                            result.append("")  # 空行
                                            i = next_end + 1
                                            while i < len(code_lines) and not code_lines[i].strip():
                                                i += 1
                                            # 标记已处理，跳过后续的输出逻辑
                                            all_inner_lines = None
                                            break
                                    else:
                                        # 普通try块
                                        next_end, next_try_id = self._find_try_block_end(
                                            code_lines, next_pos
                                        )

                                        if next_end and next_try_id == try_block_id:
                                            # 同try_block_id，继续合并
                                            try_end = next_end
                                            current_pos = next_pos
                                            continue

                            # 不能继续合并，退出
                            break

                        # 检查是否已经在 co_yield 合并中处理了
                        if all_inner_lines is None:
                            # 已经处理过了，跳过
                            continue

                        # 输出合并后的try块
                        result.append(f"{indent}try {{")
                        result.extend(all_inner_lines)

                        # 获取co_catch参数（检查是否有CO_CLEAR_STATE）
                        co_catch_line = code_lines[try_end]
                        result.append(co_catch_line)
                        result.append("")  # 空行

                        i = try_end + 1
                        # 跳过空行
                        while i < len(code_lines) and not code_lines[i].strip():
                            i += 1
                        continue

                # 不能合并或不是普通try块，直接输出
                result.append(code_lines[i])
                i += 1
            else:
                # 不是try块，直接输出
                result.append(code_lines[i])
                i += 1

        return result

    def _find_try_block_end(
        self, code_lines: list[str], start_idx: int
    ) -> tuple[Optional[int], Optional[int]]:
        """查找try块的结束位置和try_block_id

        Returns:
            (end_index, try_block_id): 结束行索引（} co_catch那一行）和try_block_id
        """
        brace_count = 0
        for i in range(start_idx, len(code_lines)):
            line = code_lines[i]

            for ch in line:
                if ch == "{":
                    brace_count += 1
                elif ch == "}":
                    brace_count -= 1

                    if brace_count == 0:
                        # 找到匹配的}，检查是否有co_catch
                        if "co_catch(" in line:
                            # 提取try_block_id
                            import re

                            match = re.search(r"co_catch\((\d+)", line)
                            if match:
                                try_block_id = int(match.group(1))
                                return i, try_block_id
                        return i, None

        return None, None

    def _find_next_try_block(
        self, code_lines: list[str], start_idx: int
    ) -> tuple[Optional[int], Optional[int]]:
        """查找下一个try块的开始位置和try_block_id

        跳过空行，找到下一个try块。

        Returns:
            (start_index, try_block_id): 开始行索引和try_block_id
        """
        for i in range(start_idx, len(code_lines)):
            line = code_lines[i].strip()

            if not line:
                # 空行，跳过
                continue
            elif line == "try {":
                # 确认不是co_yield try
                is_co_yield_try = i > 0 and "co_yield" in code_lines[i - 1]
                if not is_co_yield_try:
                    # 找到try块开始，查找其try_block_id
                    _, try_block_id = self._find_try_block_end(code_lines, i)
                    return i, try_block_id
                else:
                    # co_yield try不合并
                    return None, None
            else:
                # 遇到非try块的代码，停止查找
                return None, None

        return None, None
